mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1062661 - Part 1: Discard decoders that don't have any data in them. r=karlt
This commit is contained in:
parent
35792c7281
commit
ca88a23260
@ -180,6 +180,14 @@ public:
|
||||
// ReadMetada should be called before calling this method.
|
||||
virtual bool IsMediaSeekable() = 0;
|
||||
|
||||
MediaTaskQueue* GetTaskQueue() {
|
||||
return mTaskQueue;
|
||||
}
|
||||
|
||||
void ClearDecoder() {
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~MediaDecoderReader();
|
||||
|
||||
@ -206,10 +214,6 @@ protected:
|
||||
return mSampleDecodedCallback;
|
||||
}
|
||||
|
||||
virtual MediaTaskQueue* GetTaskQueue() {
|
||||
return mTaskQueue;
|
||||
}
|
||||
|
||||
// Queue of audio frames. This queue is threadsafe, and is accessed from
|
||||
// the audio, decoder, state machine, and main threads.
|
||||
MediaQueue<AudioData> mAudioQueue;
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL {
|
||||
mDecoder->GetReader()->BreakCycles();
|
||||
mDecoder = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -155,6 +156,7 @@ bool
|
||||
TrackBuffer::EvictData(uint32_t aThreshold)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
|
||||
|
||||
int64_t totalSize = 0;
|
||||
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
|
||||
@ -166,10 +168,14 @@ TrackBuffer::EvictData(uint32_t aThreshold)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
|
||||
for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) {
|
||||
MSE_DEBUG("TrackBuffer(%p)::EvictData decoder=%u threshold=%u toEvict=%lld",
|
||||
this, i, aThreshold, toEvict);
|
||||
toEvict -= mDecoders[i]->GetResource()->EvictData(toEvict);
|
||||
toEvict -= mInitializedDecoders[i]->GetResource()->EvictData(toEvict);
|
||||
if (!mInitializedDecoders[i]->GetResource()->GetSize() &&
|
||||
mInitializedDecoders[i] != mCurrentDecoder) {
|
||||
RemoveDecoder(mInitializedDecoders[i]);
|
||||
}
|
||||
}
|
||||
return toEvict < (totalSize - aThreshold);
|
||||
}
|
||||
@ -178,11 +184,16 @@ void
|
||||
TrackBuffer::EvictBefore(double aTime)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
|
||||
int64_t endOffset = mDecoders[i]->ConvertToByteOffset(aTime);
|
||||
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
|
||||
for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) {
|
||||
int64_t endOffset = mInitializedDecoders[i]->ConvertToByteOffset(aTime);
|
||||
if (endOffset > 0) {
|
||||
MSE_DEBUG("TrackBuffer(%p)::EvictBefore decoder=%u offset=%lld", this, i, endOffset);
|
||||
mDecoders[i]->GetResource()->EvictBefore(endOffset);
|
||||
mInitializedDecoders[i]->GetResource()->EvictBefore(endOffset);
|
||||
if (!mInitializedDecoders[i]->GetResource()->GetSize() &&
|
||||
mInitializedDecoders[i] != mCurrentDecoder) {
|
||||
RemoveDecoder(mInitializedDecoders[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,20 +469,58 @@ TrackBuffer::Dump(const char* aPath)
|
||||
}
|
||||
#endif
|
||||
|
||||
class DelayedDispatchToMainThread : public nsRunnable {
|
||||
public:
|
||||
explicit DelayedDispatchToMainThread(SourceBufferDecoder* aDecoder)
|
||||
: mDecoder(aDecoder)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL {
|
||||
// Shutdown the reader, and remove its reference to the decoder
|
||||
// so that it can't accidentally read it after the decoder
|
||||
// is destroyed.
|
||||
mDecoder->GetReader()->Shutdown();
|
||||
mDecoder->GetReader()->ClearDecoder();
|
||||
RefPtr<nsIRunnable> task = new ReleaseDecoderTask(mDecoder);
|
||||
mDecoder = nullptr;
|
||||
// task now holds the only ref to the decoder.
|
||||
NS_DispatchToMainThread(task);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<SourceBufferDecoder> mDecoder;
|
||||
};
|
||||
|
||||
void
|
||||
TrackBuffer::RemoveDecoder(SourceBufferDecoder* aDecoder)
|
||||
{
|
||||
RefPtr<nsIRunnable> task = new ReleaseDecoderTask(aDecoder);
|
||||
RefPtr<nsIRunnable> task;
|
||||
nsRefPtr<MediaTaskQueue> taskQueue;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(!mInitializedDecoders.Contains(aDecoder));
|
||||
if (mInitializedDecoders.RemoveElement(aDecoder)) {
|
||||
taskQueue = aDecoder->GetReader()->GetTaskQueue();
|
||||
task = new DelayedDispatchToMainThread(aDecoder);
|
||||
} else {
|
||||
task = new ReleaseDecoderTask(aDecoder);
|
||||
}
|
||||
mDecoders.RemoveElement(aDecoder);
|
||||
|
||||
if (mCurrentDecoder == aDecoder) {
|
||||
DiscardDecoder();
|
||||
}
|
||||
}
|
||||
// At this point, task should be holding the only reference to aDecoder.
|
||||
NS_DispatchToMainThread(task);
|
||||
if (taskQueue) {
|
||||
// If we were initialized, post the task via the reader's
|
||||
// task queue to ensure that the reader isn't in the middle
|
||||
// of an existing task.
|
||||
taskQueue->Dispatch(task);
|
||||
} else {
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user