Some invalid streams incorrectly tag all frames as keyframes, which cause the frames to be inserted in the wrong order in the trackbuffer.
MozReview-Commit-ID: EZurdiMxmle
--HG--
extra : rebase_source : d739eecb9e5b06aaeefcf044b5735949db86522d
Follow-up to bug 1259274, where TBM lost its inheritance.
MozReview-Commit-ID: 24tyq8tZYHp
--HG--
extra : rebase_source : 34dafd58ca0daca53649e04a0781bf6e23db3cbe
Handle encrypted WebM streams for the clearkey case. Add checking for the
widevine case, though these should currently fail, as not all of the plumping
is in place for widevine.
MozReview-Commit-ID: 5d9fvc5IkZF
--HG--
extra : rebase_source : 9baad2afd7778c350c404c72dcd81426092aa908
The index at which we are removing frames is always the one where we will be inserting the next ones.
MozReview-Commit-ID: DHeJDmwiMS9
--HG--
extra : rebase_source : 3730c0ed7fbdb4d9f8b4157f36aa7bb9d03a6517
We keep the next position on where to add frames so that we do not break the current coded frame group. However, when the new group of added frames starts with a keyframe we do not have to worry about breaking the previous coded frame group.
MozReview-Commit-ID: G81xGuSa4Y2
--HG--
extra : rebase_source : 4cbe5d0b5921c68c877815af15bbd10b40f18c80
The condition will be perfectly handled by the MediaFormatReader anyway.
MozReview-Commit-ID: Dm6evq6T4t6
--HG--
extra : rebase_source : 6e49cfae68bfa856aad891faf3cea565b152e565
If no keyframe are found after our time threshold, we can still skip to another keyframe (despite being prior the desired time).
So this is just a workaround for our inability to tell the MDSM when to enter buffering mode and instead the MDSM incorrectly uses the time of the last frame returned.
MozReview-Commit-ID: 5sGULpvqY5m
--HG--
extra : rebase_source : 392fe16a00eb9e10812ba4ada2e4e7c4e4aaa016
P2 let all tasks run until completion, as such we don't need to deal with interrupted tasks anymore.
MozReview-Commit-ID: 45lYcIGk2ce
--HG--
extra : rebase_source : 33438284685d8f1b48f54fd109880baf0353b976
We need to ensure that the MSE TaskQueue gets shutdown as soon as possible and not wait for the MediaSource parent to be destroyed by the cycle collector.
XPCOM shutdown will deadlock if any SharedThreadPool are still in use, and it possible for the cycle collector to only occur after xpcom has shutdown.
So it's important to ensure mTaskQueue is cleared when the MediaSourceDecoder has been shutdown.
This is done by queueing a new DetachTask that will clear mTaskQueue when run.
MozReview-Commit-ID: C3FXcRtq1wy
--HG--
extra : rebase_source : 79a7c5cb451655c4679b9d4e11d0b5ca0d9814b9
This ensures that the tasks are processed in the expected order.
MozReview-Commit-ID: JPxlwReZ4Az
--HG--
extra : rebase_source : 4ffac9deaf531c9dfd8443b2e26812d7c8a89102
P2 let all tasks run until completion, as such we don't need to deal with interrupted tasks anymore.
MozReview-Commit-ID: 45lYcIGk2ce
--HG--
extra : rebase_source : db9c8db1b3f1d51d57ad090fdeb2cad6682de2be
We need to ensure that the MSE TaskQueue gets shutdown as soon as possible and not wait for the MediaSource parent to be destroyed by the cycle collector.
XPCOM shutdown will deadlock if any SharedThreadPool are still in use, and it possible for the cycle collector to only occur after xpcom has shutdown.
So it's important to ensure mTaskQueue is cleared when the MediaSourceDecoder has been shutdown.
This is done by queueing a new DetachTask that will clear mTaskQueue when run.
MozReview-Commit-ID: C3FXcRtq1wy
--HG--
extra : rebase_source : 38c0b5548b32e89b0994704c1318ff77fba76eba
This ensures that the tasks are processed in the expected order.
MozReview-Commit-ID: JPxlwReZ4Az
--HG--
extra : rebase_source : 873a373c5a6ccf20eb69f6d36b1ebdf25e6ddea3
P1 let all tasks run until completion, as such we don't need to deal with interrupted tasks anymore.
MozReview-Commit-ID: 45lYcIGk2ce
--HG--
extra : rebase_source : 87731ae2ef2c1aa2fae57ef4b232374f9ad5e0bc
We need to ensure that the MSE TaskQueue gets shutdown as soon as possible and not wait for the MediaSource parent to be destroyed by the cycle collector.
XPCOM shutdown will deadlock if any SharedThreadPool are still in use, and it possible for the cycle collector to only occur after xpcom has shutdown.
So it's important to ensure mTaskQueue is cleared when the MediaSourceDecoder has been shutdown.
This is done by queueing a new DetachTask that will clear mTaskQueue when run.
MozReview-Commit-ID: C3FXcRtq1wy
--HG--
extra : rebase_source : 034319517bd8b90668b6311efb54c3a1a864cb5b
On Windows, it is possible for the WMF decoder to consume more than the amount of frames available before outputting the first frame. So just to produce the loadeddata event, we may have in fact already reached the end of the content. To guarantee that the "playing" event is fired, we must add more data than what was originally there.
MozReview-Commit-ID: 12eQnchNGLB
It ensures that resume from waiting for data is correct and the MediaFormatReader internal seek can handle partial GOP.
MozReview-Commit-ID: 1jyv3dajQPv
--HG--
extra : rebase_source : d9aba013aaacc9c19ee6a47ead839adda5c1299e
If the last frames of a media segment were evicted due to gap detection, mLongestFrameDuration would have been reset.
Additionally, simplify the code by using temporary variables.
MozReview-Commit-ID: HCjuZkgwANN
--HG--
extra : rebase_source : eed2837fd4b05fe3f7c4774c4486a201d0100cf7
This makes us closer to the spec, while still allowing some leeway in gap detection which was found to too strict in the past.
MozReview-Commit-ID: 9EPT2e2F6ed
--HG--
extra : rebase_source : 2bdc01667c3aaeae7a72eb5c6861076113a34c59
It had originally been added to improve speed though further changes to the processing of frames made this optimization unecessary.
And it means that we don't properly handle invalid media segment with discontinuities within their range.
MozReview-Commit-ID: wGjWEQxLX3
--HG--
extra : rebase_source : 1a14e404c9e4630cab525472978a8c6cbfbc3bd0
Some refactoring, clean-ups, etc.
The main change is that the can-play status is passed when diagnostics are
finally recorded. This will help when introducing different types of
diagnostics in future patches (e.g., Key System issues).
MozReview-Commit-ID: 182ePlrMqn4
DecoderDoctorDiagnostics are now used at places where Firefox Chrome and/or
websites checks whether some media formats may be played:
- audio|video.canPlayType()
- audio|video resource loader
- MediaSource.IsTypeSupported()
- MediaSource.AddSourceBuffer()
MozReview-Commit-ID: B1KdjXODq9j
Pass declared-but-yet-undefined DecoderDoctorDiagnostics pointer to various
routines that contribute to deciding if a media format can be played, and
those that create decoders.
Points where a DecoderDoctorDiagnostics can be injected are currently marked
with "/* DecoderDoctorDiagnostics* */ nullptr", and some will be used in
following patches.
MozReview-Commit-ID: 7u37bvY4CpW
Also, remove no longer used code and update comments to properly reflect the current algorithms used.
MozReview-Commit-ID: GwsGC70xM85
--HG--
extra : rebase_source : 2c1a2cd449eac243d8e3d77cc1bf80c2adc64cdf
20MB appears to work, but just to be safe until we get confirmation from YouTube on what is a safe value to use.
MozReview-Commit-ID: BnGaVLeCRJ5
--HG--
extra : rebase_source : 6333dd4c8dbd6f846344218dd50124797fc5cb23
Bug 1216460 introduced a regression which would cause to always evict from both ends of the current track buffer.
MozReview-Commit-ID: 4f01tNQ2KU8
--HG--
extra : rebase_source : 7da96fc1cbca03d60705fce681ee9259dd81d173
It was possible for a TrackBuffersManager to have pending tasks currently running while the MediaSourceDemuxer was shutting down the task queue. This would cause an assertion upon resolution of the promise attempting to schedule a new runnable as the task queue was now shutdown.
The AutoTaskQueue only shuts down once it's no longer used.
MozReview-Commit-ID: IzPh2OdGbvN
--HG--
extra : rebase_source : 3b39ca72f1bbb1d64e7f9f7a376b5b9cb68da0f6
Just like TaskQueue, but doesn't require to be shutdown.
MozReview-Commit-ID: 9JR9mZZuP4w
--HG--
extra : rebase_source : c98aaafdad31e34afe7a58d1113f5835f777c1c0
We now longer require an abstraction layer with the TrackBuffersManager now that the old MSE has been removed.
MozReview-Commit-ID: 3uEejohvFQD
--HG--
extra : rebase_source : 2e89fe4c7b9d13910fb6f26f0090fca26d19726f
* Move eviction handling out of SourceBuffer into TrackBuffersManager
* Separate audio and video eviction thresholds
* Reduce default audio eviction threshold to 15MB
The assumption was made that this code was never called if MediaSourceDecoder::NextFrameBufferedStatus() had been called before. However, that assumption was incorrect as NextFrameBufferedStatus() is only called if we had determine we had no frame buffered.
MozReview-Commit-ID: 1hsEJuInION
--HG--
extra : rebase_source : f760ef8df01858c24887ba024c6b350332d2e4dc
The Benchmark class is now taking a MediaDataDemuxer argument. Options allow to decode any videos and measure the decoding speed.
MozReview-Commit-ID: C017I1cGqPL
Also, an assert could have been incorrectly triggered, if eviction occurred on a source buffer while data was also being appended to it.
MozReview-Commit-ID: 6gVHZdbL07B
Also, an assert could have been incorrectly triggered, if eviction occurred on a source buffer while data was also being appended to it.
MozReview-Commit-ID: 6gVHZdbL07B
The W3C spec indicates that while everything in MSE is asynchronous, the abort() command is to interrupt the current segment parser loop and have the reset parser loop synchronously completes the frames present in the input buffer.
This causes a fundamental issue that abort() will never result in a deterministic outcome as the segment parser loop may be in different condition.
We used to really attempt to abort the current operation, however there could have been a race in the order in which tasks were queued. As such, we now simply wait for the current appendBuffer to complete.
This also simplifies the code greatly, as we don't need to worry about pending concurrent appendBuffer.
The actually happens to be similar to the Chromium behavior.
Similar to bug 1239983, we strongly assert should a segment parser loop be running when it must have completed.
MozReview-Commit-ID: 9772PLQEozf
It served no purpose other than implementing the MSE spec by the letter. The spirit is preserved.
This allows to disable tail dispatching on the MediaSourceDemuxer's TaskQueue which prevents us from performing synchronous operation on the main thread.
MozReview-Commit-ID: G7aqfvGsf1e
The changes that follow may cause the active sourcebuffer list to be modified; which will trigger an assertion if the mediasource object is closed.
MozReview-Commit-ID: 8A1CMKAUyTq
mAppendRunning is set prior the append task being queued; so it is possible that the segment parser loop hasn't yet been started, yet mAppendRunning is true.
Separate this diagnostic with a new flag ON A CLOSED TREE.
MozReview-Commit-ID: GgTyyltKOJr
The W3C spec indicates that while everything in MSE is asynchronous, the abort() command is to interrupt the current segment parser loop and have the reset parser loop synchronously completes the frames present in the input buffer.
This causes a fundamental issue that abort() will never result in a deterministic outcome as the segment parser loop may be in different condition.
We used to really attempt to abort the current operation, however there could have been a race in the order in which tasks were queued. As such, we now simply wait for the current appendBuffer to complete.
This also simplifies the code greatly, as we don't need to worry about pending concurrent appendBuffer.
The actually happens to be similar to the Chromium behavior.
Similar to bug 1239983, we strongly assert should a segment parser loop be running when it must have completed.
MozReview-Commit-ID: 9772PLQEozf
It served no purpose other than implementing the MSE spec by the letter. The spirit is preserved.
This allows to disable tail dispatching on the MediaSourceDemuxer's TaskQueue which prevents us from performing synchronous operation on the main thread.
MozReview-Commit-ID: G7aqfvGsf1e
The changes that follow may cause the active sourcebuffer list to be modified; which will trigger an assertion if the mediasource object is closed.
MozReview-Commit-ID: 8A1CMKAUyTq
This is similar to bug 1239983, we strongly assert should a segment parser loop be running when it must have completed.
MozReview-Commit-ID: CXqGoq9Opq0
The W3C spec indicates that while everything in MSE is asynchronous, the abort() command is to interrupt the current segment parser loop and have the reset parser loop synchronously completes the frames present in the input buffer.
This causes a fundamental issue that abort() will never result in a deterministic outcome as the segment parser loop may be in different condition.
We used to really attempt to abort the current operation, however there could have been a race in the order in which tasks were queued. As such, we now simply wait for the current appendBuffer to complete.
This also simplifies the code greatly, as we don't need to worry about pending concurrent appendBuffer.
The actually happens to be similar to the Chromium behavior.
MozReview-Commit-ID: CHppUOGM1mk
The changes that follow may cause the active sourcebuffer list to be modified; which will trigger an assertion if the mediasource object is closed.
MozReview-Commit-ID: 8A1CMKAUyTq
YouTube sets the track ID at 1 for both audio and video tracks. Attempting to use mozCaptureStream would cause an assert as it always expect tracks to have a different track Id.
Added diagnostics around demuxer init/reset promises, to catch early cases
where TrackBuffersManager::mInputDemuxer is destroyed while an init/reset
promise is in flight, which would cause later issues when the 'Then' clause
assumes that mInputDemuxer still exists.
Note: This is *not* an actual fix for crashes linked to this bug, but it should
help identify unexpected situations, or instead eliminate these patched
locations as sources of crashes.
A new bug will be needed to examine the fallout from this patch and produce a
real fix, or continue investigating.
XPCOM when shutting down expects all tasks to be run synchronously. As such, we must ensure that the remaining MediaDecoder are shut down before continuing on the next task.
In particular destroying gfxPlatforms must only ever happen after, as it is possible for the MediaDecoderReader to make use of gfx resources during shutdown.
When seeking, the next keyframe time would always be set to the seek time (as the next sample to be retrieved would be a keyframe). This could lead to the next key frame logic to be activated too aggressively.
When seeking, the next keyframe time would always be set to the seek time (as the next sample to be retrieved would be a keyframe). This could lead to the next key frame logic to be activated too aggressively.
We assume that if we have 30s of data buffered ahead of the current position or up to the element's duration that we can play ahead without interruption.
We require a slightly variation on the default implementation as mediasource allows for gaps of up to 125ms between samples and often videos do not start with a time of 0.
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
This commit was generated using the following script, executed at the
top level of a typical source code checkout.
# Don't modify select files in mfbt/ because it's not worth trying to
# tease out the dependencies currently.
#
# Don't modify anything in media/gmp-clearkey/0.1/ because those files
# use their own RefPtr, defined in their own RefCounted.h.
find . -name '*.cpp' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
grep -v 'mfbt/RefPtr.h' | \
grep -v 'mfbt/nsRefPtr.h' | \
grep -v 'mfbt/RefCounted.h' | \
grep -v 'media/gmp-clearkey/0.1/' | \
xargs perl -p -i -e '
s/mozilla::RefPtr/nsRefPtr/g; # handle declarations in headers
s/\bRefPtr</nsRefPtr</g; # handle local variables in functions
s#mozilla/RefPtr.h#mozilla/nsRefPtr.h#; # handle #includes
s#mfbt/RefPtr.h#mfbt/nsRefPtr.h#; # handle strange #includes
'
# |using mozilla::RefPtr;| is OK; |using nsRefPtr;| is invalid syntax.
find . -name '*.cpp' -o -name '*.mm' | xargs sed -i -e '/using nsRefPtr/d'
# RefPtr.h used |byRef| for dealing with COM-style outparams.
# nsRefPtr.h uses |getter_AddRefs|.
# Fixup that mismatch.
find . -name '*.cpp' -o -name '*.h'| \
xargs perl -p -i -e 's/byRef/getter_AddRefs/g'
The LayersBackend can be defined at construction time, however if a parent MediaDecoder exists, the value will be overwritten by the MediaDecoderOwner value.
--HG--
extra : rebase_source : fefad83560d5bfa2aee9f665fe138397eb390019
When ffmpeg is enabled, it will use the FFmpeg's VPX decoder. FFmpeg appears to always buffer 15 frames before returning one (this is the same with h264) causing the waiting event to be fired much earlier than when using libvpx
A MediaDataDemuxer is now not to resolve the init promise until it has all the metadata.
Except MediaSource, all demuxers would be doing blocking read to scan for the metadata, and having partial metadata would be an error.
For MediaSource, we pass the NotifyDataArrived message which will cause the MediaSourceDemuxer to re-attempt to search for the metadata.
When used within MediaSource's TrackBuffersManager, a demuxer will never be created until we have received a complete init segment (this task is performed by the various ContainerParsers)