-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MockSourceBufferPrivate should only process samples once init segment has been processed. #11599
Conversation
4ba99ec
to
33bc608
Compare
@@ -151,10 +152,17 @@ void SourceBufferPrivate::updateBufferedFromTrackBuffers(bool sourceIsEnded) | |||
setBufferedRanges(intersectionRanges); | |||
} | |||
|
|||
void SourceBufferPrivate::appendCompleted(bool parsingSucceeded, bool isEnded) | |||
void SourceBufferPrivate::appendCompleted(bool parsingSucceeded, bool isEnded, Function<void()>&& preAppendCompletedTask) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be a CompletionHandler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. As it may not always be run (such as if abort()
is called in between or if an error occurred.
|
||
if (m_processingInitializationSegment) { | ||
DEBUG_LOG(LOGIDENTIFIER, originalSample.get()); | ||
// TODO: MediaSample should use uint64_t for trackID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjectIdentifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TrackID is used everywhere, and it's either an int or a uint everywhere but with MediaSample. so we have to keep doing string conversion back and forth
|
||
WeakPtr<SourceBufferPrivateClient> m_client; | ||
|
||
bool m_processingInitializationSegment { false }; | ||
Vector<std::pair<uint64_t, Ref<MediaSample>>> m_pendingMediaSamples; | ||
bool m_hasPendingAppendCompleted { false }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make these private instead?
m_processingInitializationSegment is accessed, how about just adding a protected getter but no setter for instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -171,6 +179,14 @@ class SourceBufferPrivate | |||
void trySignalAllSamplesInTrackEnqueued(TrackBuffer&, const AtomString& trackID); | |||
MediaTime findPreviousSyncSamplePresentationTime(const MediaTime&); | |||
bool evictFrames(uint64_t newDataSize, uint64_t maximumBufferSize, const MediaTime& currentTime, bool isEnded); | |||
void processPendingSamples(); | |||
|
|||
struct appendCompletedArguments { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/appendCompletedArguments/AppendCompletedArguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
{ | ||
DEBUG_LOG(LOGIDENTIFIER); | ||
|
||
if (m_processingInitializationSegment) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ASSERT(!m_appendCompletedPending); ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, there could be two init segment appended with a media segment.
like so:
init_segment | media_segment | init_segment
Actually, I think our handling of such scenario is problematic and would result in an undefined behaviour , in particular in regards to track ID ; it is possible for track id to change in between run, even get swapped between audio and video (we even have a test about it: as it used to cause a crash).
However, the behaviour following these changes is identical to what we had before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we file a bug and add a comment here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the issue I described isn't happening here. appendCompleted() can be called whenever the SourceBufferParser has finished demuxing all data but the init segment is yet to be processed by the SourceBuffer in the content process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_processingInitializationSegment = false; | ||
// 4.5.2 Reset Parser State | ||
// 1. If the [[append state]] equals PARSING_MEDIA_SEGMENT and the [[input buffer]] contains some complete coded frames, then run the coded frame processing algorithm until all of these complete coded frames have been processed. | ||
processPendingSamples(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about m_appendCompletedPending, should we reset it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so yes. good spotting
@@ -207,10 +208,8 @@ class SourceBufferPrivateAVFObjC final | |||
WeakPtrFactory<SourceBufferPrivateAVFObjC> m_appendWeakFactory; | |||
|
|||
Ref<SourceBufferParser> m_parser; | |||
bool m_processingInitializationSegment { false }; | |||
bool m_hasPendingAppendCompletedCallback { false }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no
m_processingInitializationSegment = false; | ||
processPendingSamples(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You always clear m_processingInitializationSegment
before calling processPendingSamples
, maybe do it in processPendingSamples
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would allow for unwanted side effects if it was to handle the case I described earlier (two init segments appended consecutively). So I prefer not to and leave this utility methods to do just what the name states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there ever a case where m_processingInitializationSegment
is true in processPendingSamples()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes there is. It can be called when the first didReceivedInitializatingSegment completion handler is run, but in between we received a new init segment.
EWS run on previous version of this PR (hash 33bc608) |
EWS run on previous version of this PR (hash 4ba99ec) |
33bc608
to
d1f4a65
Compare
EWS run on current version of this PR (hash d1f4a65) |
β¦ has been processed. https://bugs.webkit.org/show_bug.cgi?id=253997 rdar://106784564 Reviewed by Youenn Fablet. The ability of a SourceBufferPrivate to run in the GPU process required some steps to be done asynchronously. In particular no demuxed media segments should be processed until all track buffers had been created as they would otherwise be dropped. Currently, only the SourceBufferPrivateAVFObjC implementation had been modified to run asynchronously and contained very specific handlings to do so. We move the responsibility of queuing samples for until the init segment has been fully processed to the base SourceBufferPrivate class. We allows the ability for any SourceBufferPrivate implementation to be wrapped in a SourceBufferPrivateRemote and be platform agnostic, including the MockMediaSource. Fly-by changes: - Rename ReceiveResult::RecieveSucceeded to ReceiveResult::Succeeded (and fix typo) - Rename AppendResult::AppendSucceeded to AppendResult::Succeeded - By spec, the Reset Parser State should process any frames left in the input buffer. * Source/WebCore/Modules/mediasource/SourceBuffer.cpp: (WebCore::SourceBuffer::appendBufferTimerFired): (WebCore::SourceBuffer::sourceBufferPrivateAppendComplete): (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment): * Source/WebCore/platform/graphics/SourceBufferPrivate.cpp: (WebCore::SourceBufferPrivate::appendCompleted): (WebCore::SourceBufferPrivate::didReceiveInitializationSegment): (WebCore::SourceBufferPrivate::didReceiveSampleForTrackId): (WebCore::SourceBufferPrivate::didReceiveSample): (WebCore::SourceBufferPrivate::processPendingSamples): (WebCore::SourceBufferPrivate::resetParserState): Make default implementation. * Source/WebCore/platform/graphics/SourceBufferPrivate.h: (WebCore::SourceBufferPrivate::appendCompleted): * Source/WebCore/platform/graphics/SourceBufferPrivateClient.cpp: (WebCore::convertEnumerationToString): * Source/WebCore/platform/graphics/SourceBufferPrivateClient.h: Rename enum as name already contained in type. * Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h: * Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h: * Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm: (WebCore::SourceBufferPrivateAVFObjC::didParseInitializationData): (WebCore::SourceBufferPrivateAVFObjC::didProvideMediaDataForTrackId): (WebCore::SourceBufferPrivateAVFObjC::processPendingTrackChangeTasks): (WebCore::SourceBufferPrivateAVFObjC::didReceiveSampleForTrackId): (WebCore::SourceBufferPrivateAVFObjC::append): (WebCore::SourceBufferPrivateAVFObjC::appendCompleted): (WebCore::SourceBufferPrivateAVFObjC::resetParserState): * Source/WebCore/platform/graphics/gstreamer/mse/SourceBufferPrivateGStreamer.cpp: (WebCore::SourceBufferPrivateGStreamer::resetParserState): * Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp: Remove unnecessary method. (WebCore::MockSourceBufferPrivate::resetParserState): Deleted. * Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h: Remove unnecessary method. Canonical link: https://commits.webkit.org/261799@main
d1f4a65
to
30fd635
Compare
Committed 261799@main (30fd635): https://commits.webkit.org/261799@main Reviewed commits have been landed. Closing PR #11599 and removing active labels. |
30fd635
d1f4a65
π iosπ macπ wpeπ wincairoπ§ͺ bindingsπ ios-simπ mac-AS-debugπ§ͺ wpe-wk2π§ͺ ios-wk2π§ͺ api-macπ§ͺ api-iosπ§ͺ mac-wk1π§ͺ gtk-wk2π tvπ§ͺ mac-wk2π tv-simπ§ͺ mac-AS-debug-wk2π watchπ§ͺ mac-wk2-stress