зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1040563 - Move WaitForData/NotifyGotData from MediaSource to MediaSourceDecoder, which is off-main-thread friendly. r=cajbir
Also remove mMediaSource from MediaSourceReader and rejig SetMediaSourceDuration to go via MediaSourceDecoder and handle mMediaSource being null.
This commit is contained in:
Родитель
c553b77d97
Коммит
feab012c39
|
@ -377,7 +377,6 @@ MediaSource::MediaSource(nsPIDOMWindow* aWindow)
|
|||
, mDuration(UnspecifiedNaN<double>())
|
||||
, mDecoder(nullptr)
|
||||
, mReadyState(MediaSourceReadyState::Closed)
|
||||
, mWaitForDataMonitor("MediaSource.WaitForData.Monitor")
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mSourceBuffers = new SourceBufferList(this);
|
||||
|
@ -465,22 +464,6 @@ MediaSource::NotifyEvicted(double aStart, double aEnd)
|
|||
mSourceBuffers->Evict(aStart, aEnd);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSource::WaitForData()
|
||||
{
|
||||
MSE_DEBUG("MediaSource(%p)::WaitForData()", this);
|
||||
MonitorAutoLock mon(mWaitForDataMonitor);
|
||||
mon.Wait();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSource::NotifyGotData()
|
||||
{
|
||||
MSE_DEBUG("MediaSource(%p)::NotifyGotData()", this);
|
||||
MonitorAutoLock mon(mWaitForDataMonitor);
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
nsPIDOMWindow*
|
||||
MediaSource::GetParentObject() const
|
||||
{
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/MediaSourceBinding.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionNoteChild.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
@ -91,12 +90,6 @@ public:
|
|||
// that were evicted are provided.
|
||||
void NotifyEvicted(double aStart, double aEnd);
|
||||
|
||||
// Block thread waiting for data to be appended to a SourceBuffer.
|
||||
void WaitForData();
|
||||
|
||||
// Unblock threads waiting for data to be appended to a SourceBuffer.
|
||||
void NotifyGotData();
|
||||
|
||||
private:
|
||||
~MediaSource();
|
||||
|
||||
|
@ -116,10 +109,6 @@ private:
|
|||
nsRefPtr<MediaSourceDecoder> mDecoder;
|
||||
|
||||
MediaSourceReadyState mReadyState;
|
||||
|
||||
// Monitor for waiting for when new data is appended to
|
||||
// a Source Buffer.
|
||||
Monitor mWaitForDataMonitor;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)
|
||||
|
|
|
@ -47,7 +47,7 @@ MediaSourceDecoder::Clone()
|
|||
MediaDecoderStateMachine*
|
||||
MediaSourceDecoder::CreateStateMachine()
|
||||
{
|
||||
mReader = new MediaSourceReader(this, mMediaSource);
|
||||
mReader = new MediaSourceReader(this);
|
||||
return new MediaDecoderStateMachine(this, mReader);
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,10 @@ MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
|
|||
nsresult
|
||||
MediaSourceDecoder::GetSeekable(dom::TimeRanges* aSeekable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mMediaSource) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
double duration = mMediaSource->Duration();
|
||||
if (IsNaN(duration)) {
|
||||
// Return empty range.
|
||||
|
@ -86,6 +90,16 @@ MediaSourceDecoder::GetSeekable(dom::TimeRanges* aSeekable)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::Shutdown()
|
||||
{
|
||||
MediaDecoder::Shutdown();
|
||||
|
||||
// Kick WaitForData out of its slumber.
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
already_AddRefed<MediaResource>
|
||||
MediaSourceDecoder::CreateResource()
|
||||
|
@ -96,13 +110,14 @@ MediaSourceDecoder::CreateResource()
|
|||
void
|
||||
MediaSourceDecoder::AttachMediaSource(dom::MediaSource* aMediaSource)
|
||||
{
|
||||
MOZ_ASSERT(!mMediaSource && !mDecoderStateMachine);
|
||||
MOZ_ASSERT(!mMediaSource && !mDecoderStateMachine && NS_IsMainThread());
|
||||
mMediaSource = aMediaSource;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::DetachMediaSource()
|
||||
{
|
||||
MOZ_ASSERT(mMediaSource && NS_IsMainThread());
|
||||
mMediaSource = nullptr;
|
||||
}
|
||||
|
||||
|
@ -113,4 +128,31 @@ MediaSourceDecoder::CreateSubDecoder(const nsACString& aType)
|
|||
return mReader->CreateSubDecoder(aType);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::SetMediaSourceDuration(double aDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mMediaSource) {
|
||||
return;
|
||||
}
|
||||
ErrorResult dummy;
|
||||
mMediaSource->SetDuration(aDuration, dummy);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::WaitForData()
|
||||
{
|
||||
MSE_DEBUG("MediaSourceDecoder(%p)::WaitForData()", this);
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mon.Wait();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::NotifyGotData()
|
||||
{
|
||||
MSE_DEBUG("MediaSourceDecoder(%p)::NotifyGotData()", this);
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
virtual nsresult Load(nsIStreamListener**, MediaDecoder*) MOZ_OVERRIDE;
|
||||
virtual nsresult GetSeekable(dom::TimeRanges* aSeekable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Shutdown() MOZ_OVERRIDE;
|
||||
|
||||
static already_AddRefed<MediaResource> CreateResource();
|
||||
|
||||
void AttachMediaSource(dom::MediaSource* aMediaSource);
|
||||
|
@ -45,6 +47,14 @@ public:
|
|||
|
||||
already_AddRefed<SourceBufferDecoder> CreateSubDecoder(const nsACString& aType);
|
||||
|
||||
void SetMediaSourceDuration(double aDuration);
|
||||
|
||||
// Provide a mechanism for MediaSourceReader to block waiting on data from a SourceBuffer.
|
||||
void WaitForData();
|
||||
|
||||
// Called whenever a SourceBuffer has new data appended.
|
||||
void NotifyGotData();
|
||||
|
||||
private:
|
||||
// The owning MediaSource holds a strong reference to this decoder, and
|
||||
// calls Attach/DetachMediaSource on this decoder to set and clear
|
||||
|
|
|
@ -35,12 +35,11 @@ extern PRLogModuleInfo* GetMediaSourceAPILog();
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder, dom::MediaSource* aSource)
|
||||
MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
|
||||
: MediaDecoderReader(aDecoder)
|
||||
, mTimeThreshold(-1)
|
||||
, mDropAudioBeforeThreshold(false)
|
||||
, mDropVideoBeforeThreshold(false)
|
||||
, mMediaSource(aSource)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -249,14 +248,6 @@ MediaSourceReader::SwitchReaders(SwitchType aType)
|
|||
return didSwitch;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::SetMediaSourceDuration(double aDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ErrorResult dummy;
|
||||
mMediaSource->SetDuration(aDuration, dummy);
|
||||
}
|
||||
|
||||
class ReleaseDecodersTask : public nsRunnable {
|
||||
public:
|
||||
ReleaseDecodersTask(nsTArray<nsRefPtr<SourceBufferDecoder>>& aDecoders)
|
||||
|
@ -423,7 +414,7 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
|||
// we'll remove this for an async approach based on that in bug XXXXXXX.
|
||||
while (!DecodersContainTime(target) && !IsShutdown()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek waiting for target=%f", this, target);
|
||||
mMediaSource->WaitForData();
|
||||
static_cast<MediaSourceDecoder*>(mDecoder)->WaitForData();
|
||||
SwitchReaders(SWITCH_FORCED);
|
||||
}
|
||||
|
||||
|
@ -491,7 +482,8 @@ MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
|
|||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->SetMediaDuration(maxDuration);
|
||||
nsRefPtr<nsIRunnable> task (
|
||||
NS_NewRunnableMethodWithArg<double>(this, &MediaSourceReader::SetMediaSourceDuration,
|
||||
NS_NewRunnableMethodWithArg<double>(static_cast<MediaSourceDecoder*>(mDecoder),
|
||||
&MediaSourceDecoder::SetMediaSourceDuration,
|
||||
static_cast<double>(maxDuration) / USECS_PER_S));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class MediaSource;
|
|||
class MediaSourceReader : public MediaDecoderReader
|
||||
{
|
||||
public:
|
||||
MediaSourceReader(MediaSourceDecoder* aDecoder, dom::MediaSource* aSource);
|
||||
MediaSourceReader(MediaSourceDecoder* aDecoder);
|
||||
|
||||
nsresult Init(MediaDecoderReader* aCloneDonor) MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -98,8 +98,6 @@ private:
|
|||
bool SwitchAudioReader(MediaDecoderReader* aTargetReader);
|
||||
bool SwitchVideoReader(MediaDecoderReader* aTargetReader);
|
||||
|
||||
void SetMediaSourceDuration(double aDuration) ;
|
||||
|
||||
// These are read and written on the decode task queue threads.
|
||||
int64_t mTimeThreshold;
|
||||
bool mDropAudioBeforeThreshold;
|
||||
|
@ -110,8 +108,6 @@ private:
|
|||
|
||||
nsRefPtr<MediaDecoderReader> mAudioReader;
|
||||
nsRefPtr<MediaDecoderReader> mVideoReader;
|
||||
|
||||
dom::MediaSource* mMediaSource;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -499,7 +499,7 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
|
|||
// if required when data is appended.
|
||||
mMediaSource->GetDecoder()->ScheduleStateMachineThread();
|
||||
|
||||
mMediaSource->NotifyGotData();
|
||||
mMediaSource->GetDecoder()->NotifyGotData();
|
||||
}
|
||||
|
||||
double
|
||||
|
|
Загрузка…
Ссылка в новой задаче