Open Bug 1578848 Opened 5 years ago Updated 2 years ago

TrackBuffersManager's buffered ranges can be empty when evicting data

Categories

(Core :: Audio/Video: Playback, defect, P2)

defect

Tracking

()

People

(Reporter: bryce, Unassigned)

References

Details

Bug 1578143 happens because TrackBuffersManager can have empty ranges while attempting to evict data. It appears to me this shouldn't happen because of the following

  • Attempting to evict data suggests the existence of buffered media data.
  • The existence of media data implies the existence of one or more buffered range representing the time interval(s) of the buffered media data.
  • Therefore, when evicting data there should be one or more buffered ranges.

My suggested fix in bug 1578143 should address the crash resulting from the lack of buffered range, but it won't fix that we can arrive in that state. This bug is track the underlying issue that we can have data but no buffered range.

Detailing investigation as I go:

Adding

MOZ_ASSERT_IF(aTrackData.mBufferedRanges.Length() == 0, data.IsEmpty());

to the end of RemoveFrames catches this on videos at animeflv.net, though it took me ~15 minutes to trigger the assert.


>	xul.dll!mozilla::TrackBuffersManager::RemoveFrames(const mozilla::media::TimeIntervals & aIntervals, mozilla::TrackBuffersManager::TrackData & aTrackData, unsigned int aStartIndex, mozilla::TrackBuffersManager::RemovalMode aMode) Line 2234	C++
 	xul.dll!mozilla::TrackBuffersManager::CodedFrameRemoval(mozilla::media::Interval<mozilla::media::TimeUnit> aInterval) Line 654	C++
 	xul.dll!mozilla::TrackBuffersManager::ProcessTasks() Line 230	C++
 	xul.dll!mozilla::TrackBuffersManager::QueueTask(mozilla::SourceBufferTask * aTask) Line 171	C++
 	xul.dll!mozilla::TrackBuffersManager::CodedFrameRemovalWithPromise(mozilla::media::Interval<mozilla::media::TimeUnit> aInterval) Line 586	C++
 	xul.dll!mozilla::detail::RunnableMethodArguments<StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > >::applyImpl<mozilla::TrackBuffersManager,RefPtr<mozilla::MozPromise<bool,nsresult,1> > (mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>),StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > ,0>(mozilla::TrackBuffersManager * o, RefPtr<mozilla::MozPromise<bool,nsresult,1> >(mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>) m, mozilla::Tuple<StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > > & args, std::integer_sequence<unsigned long long,0>) Line 1124	C++
 	xul.dll!mozilla::detail::RunnableMethodArguments<StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > >::apply<mozilla::TrackBuffersManager,RefPtr<mozilla::MozPromise<bool,nsresult,1> > (mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>)>(mozilla::TrackBuffersManager * o, RefPtr<mozilla::MozPromise<bool,nsresult,1> >(mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>) m) Line 1130	C++
 	xul.dll!mozilla::detail::MethodCall<mozilla::MozPromise<bool,nsresult,1>,RefPtr<mozilla::MozPromise<bool,nsresult,1> > (mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>),mozilla::TrackBuffersManager,StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > >::Invoke() Line 1313	C++
 	xul.dll!mozilla::detail::ProxyRunnable<mozilla::MozPromise<bool,nsresult,1>,RefPtr<mozilla::MozPromise<bool,nsresult,1> > (mozilla::TrackBuffersManager::*)(mozilla::media::Interval<mozilla::media::TimeUnit>),mozilla::TrackBuffersManager,StoreCopyPassByRRef<mozilla::media::Interval<mozilla::media::TimeUnit> > >::Run() Line 1333	C++
 	xul.dll!mozilla::TaskQueue::Runner::Run() Line 200	C++
 	xul.dll!nsThreadPool::Run() Line 246	C++
 	xul.dll!nsThread::ProcessNextEvent(bool aMayWait, bool * aResult) Line 1227	C++
 	xul.dll!NS_ProcessNextEvent(nsIThread * aThread, bool aMayWait) Line 486	C++
 	xul.dll!mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate * aDelegate) Line 334	C++
 	xul.dll!MessageLoop::RunInternal() Line 315	C++
 	xul.dll!MessageLoop::RunHandler() Line 309	C++
 	xul.dll!MessageLoop::Run() Line 291	C++
 	xul.dll!nsThread::ThreadFunc(void * aArg) Line 460	C++
 	nss3.dll!_PR_NativeRunThread(void * arg) Line 406	C
 	nss3.dll!pr_root(void * arg) Line 137	C
 	[External Code]	
 	mozglue.dll!mozilla::interceptor::FuncHook<mozilla::interceptor::WindowsDllInterceptor<mozilla::interceptor::VMSharingPolicyShared<mozilla::interceptor::MMPolicyInProcess,1> >,void (*)(int, void *, void *)>::operator()<int,void *,void *>(int aArgs, void * aArgs, void * aArgs) Line 141	C++
 	mozglue.dll!patched_BaseThreadInitThunk(int aIsInitialThread, void * aStartAddress, void * aThreadParam) Line 603	C++
 	[External Code]	

At that time data has a length of 57372, and all the media data I inspect in data has mTime == mTimeCode == mDuration == 0.
Dumps of var values at time of assert:

aIntervals.GetStart(nullptr)	{mValue={mValue=243668333 mIsValid=true } }	mozilla::media::TimeUnit
aIntervals.GetEnd(nullptr)	{mValue={mValue=571668333 mIsValid=true } }	mozilla::media::TimeUnit
removedIntervals.GetStart(nullptr)	{mValue={mValue=243668333 mIsValid=true } }	mozilla::media::TimeUnit
removedIntervals.GetEnd(nullptr)	{mValue={mValue=571668333 mIsValid=true } }	mozilla::media::TimeUnit

The above intervals only have 1 member in each set, so they're continuous between those starts and ends.

firstRemovedIndex.ref()	57372	unsigned int &
lastRemovedIndex	72746	unsigned int

So it looks like we have removed some data from the end of our buffer, and have removed the range associated with that data. However, we're left with a whole lot of 0 duration data at the start of our buffer. I wonder if it's being appended in some bogus append and that the bug is even earlier? Will try adding more asserts and seeing what I turn up.

Unassigning bugs assigned to Bryce because he no longer works at Mozilla.

Assignee: brycebugemail → nobody
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.