Rework MediaDecoder::AddOutputStream and move related code to the MDSM

This commit is contained in:
trav90
2017-10-25 04:34:49 -05:00
committed by Roy Tam
parent 73a091c648
commit e98562dc6d
7 changed files with 70 additions and 63 deletions
+2 -2
View File
@@ -180,7 +180,7 @@ DecodedStream::DecodedStream(ReentrantMonitor& aMonitor)
}
DecodedStreamData*
DecodedStream::GetData()
DecodedStream::GetData() const
{
GetReentrantMonitor().AssertCurrentThreadIn();
return mData.get();
@@ -252,7 +252,7 @@ DecodedStream::OutputStreams()
}
ReentrantMonitor&
DecodedStream::GetReentrantMonitor()
DecodedStream::GetReentrantMonitor() const
{
return mMonitor;
}
+2 -2
View File
@@ -90,11 +90,11 @@ public:
class DecodedStream {
public:
explicit DecodedStream(ReentrantMonitor& aMonitor);
DecodedStreamData* GetData();
DecodedStreamData* GetData() const;
void DestroyData();
void RecreateData(int64_t aInitialTime, MediaStreamGraph* aGraph);
nsTArray<OutputStreamData>& OutputStreams();
ReentrantMonitor& GetReentrantMonitor();
ReentrantMonitor& GetReentrantMonitor() const;
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
private:
+1 -25
View File
@@ -300,29 +300,12 @@ void MediaDecoder::SetVolume(double aVolume)
mVolume = aVolume;
}
void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
DECODER_LOG("RecreateDecodedStream aStartTimeUSecs=%lld!", aStartTimeUSecs);
mDecodedStream.RecreateData(aStartTimeUSecs, MediaStreamGraph::GetInstance());
}
void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
bool aFinishWhenEnded)
{
MOZ_ASSERT(NS_IsMainThread());
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load().");
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!GetDecodedStream()) {
RecreateDecodedStream(mLogicalPosition);
}
mDecodedStream.Connect(aStream, aFinishWhenEnded);
mDecoderStateMachine->DispatchAudioCaptured();
mDecoderStateMachine->AddOutputStream(aStream, aFinishWhenEnded);
}
double MediaDecoder::GetDuration()
@@ -371,7 +354,6 @@ MediaDecoder::MediaDecoder() :
mMediaSeekable(true),
mSameOriginMedia(false),
mReentrantMonitor("media.decoder"),
mDecodedStream(mReentrantMonitor),
mEstimatedDuration(AbstractThread::MainThread(), NullableTimeUnit(),
"MediaDecoder::mEstimatedDuration (Canonical)"),
mExplicitDuration(AbstractThread::MainThread(), Maybe<double>(),
@@ -463,12 +445,6 @@ void MediaDecoder::Shutdown()
MediaDecoder::~MediaDecoder()
{
MOZ_ASSERT(NS_IsMainThread());
{
// Don't destroy the decoded stream until destructor in order to keep the
// invariant that the decoded stream is always available in capture mode.
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mDecodedStream.DestroyData();
}
MediaMemoryTracker::RemoveMediaDecoder(this);
UnpinForSeek();
MOZ_COUNT_DTOR(MediaDecoder);
-21
View File
@@ -391,20 +391,6 @@ public:
// replaying after the input as ended. In the latter case, the new source is
// not connected to streams created by captureStreamUntilEnded.
/**
* Recreates mDecodedStream. Call this to create mDecodedStream at first,
* and when seeking, to ensure a new stream is set up with fresh buffers.
* aStartTimeUSecs is relative to the state machine's mStartTime.
* Decoder monitor must be held.
*/
void RecreateDecodedStream(int64_t aStartTimeUSecs);
DecodedStreamData* GetDecodedStream()
{
GetReentrantMonitor().AssertCurrentThreadIn();
return mDecodedStream.GetData();
}
// Add an output stream. All decoder output will be sent to the stream.
// The stream is initially blocked. The decoder is responsible for unblocking
// it while it is playing back.
@@ -977,13 +963,6 @@ private:
ReentrantMonitor mReentrantMonitor;
protected:
// The SourceMediaStream we are using to feed the mOutputStreams. This stream
// is never exposed outside the decoder.
// Only written on the main thread while holding the monitor. Therefore it
// can be read on any thread while holding the monitor, or on the main thread
// without holding the monitor.
DecodedStream mDecodedStream;
// Media duration according to the demuxer's current estimate.
//
// Note that it's quite bizarre for this to live on the main thread - it would
+40 -10
View File
@@ -252,7 +252,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mDecodingFrozenAtStateDecoding(false),
mSentLoadedMetadataEvent(false),
mSentFirstFrameLoadedEvent(false),
mSentPlaybackEndedEvent(false)
mSentPlaybackEndedEvent(false),
mDecodedStream(mDecoder->GetReentrantMonitor())
{
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@@ -447,7 +448,7 @@ void MediaDecoderStateMachine::SendStreamData()
AssertCurrentThreadInMonitor();
MOZ_ASSERT(!mAudioSink, "Should've been stopped in RunStateMachine()");
DecodedStreamData* stream = mDecoder->GetDecodedStream();
DecodedStreamData* stream = GetDecodedStream();
bool finished =
(!mInfo.HasAudio() || AudioQueue().IsFinished()) &&
@@ -626,7 +627,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
return true;
}
DecodedStreamData* stream = mDecoder->GetDecodedStream();
DecodedStreamData* stream = GetDecodedStream();
if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishAudio) {
MOZ_ASSERT(mInfo.HasAudio());
@@ -650,7 +651,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedVideo()
return false;
}
DecodedStreamData* stream = mDecoder->GetDecodedStream();
DecodedStreamData* stream = GetDecodedStream();
if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishVideo) {
MOZ_ASSERT(mInfo.HasVideo());
@@ -1880,8 +1881,9 @@ MediaDecoderStateMachine::InitiateSeek()
// as far as fast-seek is concerned. It also fix the problem where stream
// clock seems to go backwards during seeking.
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethodWithArg<int64_t>(mDecoder, &MediaDecoder::RecreateDecodedStream,
seekTime - mStartTime);
NS_NewRunnableMethodWithArg<int64_t>(this,
&MediaDecoderStateMachine::RecreateDecodedStream,
seekTime - mStartTime);
AbstractThread::MainThread()->Dispatch(event.forget());
}
@@ -2728,7 +2730,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
// end of the media, and so that we update the readyState.
if (VideoQueue().GetSize() > 0 ||
(HasAudio() && !mAudioCompleted) ||
(mAudioCaptured && !mDecoder->GetDecodedStream()->IsFinished()))
(mAudioCaptured && !GetDecodedStream()->IsFinished()))
{
AdvanceFrame();
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
@@ -2909,7 +2911,7 @@ int64_t MediaDecoderStateMachine::GetClock() const
clock_time = mPlayDuration + mStartTime;
} else {
if (mAudioCaptured) {
clock_time = mStartTime + mDecoder->GetDecodedStream()->GetClock();
clock_time = mStartTime + GetDecodedStream()->GetClock();
} else if (HasAudio() && !mAudioCompleted) {
clock_time = GetAudioClock();
} else {
@@ -3511,6 +3513,12 @@ void MediaDecoderStateMachine::OnAudioSinkError()
DecodeError();
}
DecodedStreamData* MediaDecoderStateMachine::GetDecodedStream() const
{
AssertCurrentThreadInMonitor();
return mDecodedStream.GetData();
}
void MediaDecoderStateMachine::DispatchAudioCaptured()
{
nsRefPtr<MediaDecoderStateMachine> self = this;
@@ -3526,11 +3534,25 @@ void MediaDecoderStateMachine::DispatchAudioCaptured()
TaskQueue()->Dispatch(r.forget());
}
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
bool aFinishWhenEnded)
{
MOZ_ASSERT(NS_IsMainThread());
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (!GetDecodedStream()) {
RecreateDecodedStream(mCurrentPosition.ReadOnWrongThread());
}
mDecodedStream.Connect(aStream, aFinishWhenEnded);
DispatchAudioCaptured();
}
void MediaDecoderStateMachine::UpdateStreamBlockingForPlayState()
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
auto stream = mDecoder->GetDecodedStream();
auto stream = GetDecodedStream();
if (!stream) {
return;
}
@@ -3547,7 +3569,7 @@ void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
{
AssertCurrentThreadInMonitor();
auto stream = mDecoder->GetDecodedStream();
auto stream = GetDecodedStream();
if (!stream) {
return;
}
@@ -3559,6 +3581,14 @@ void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
}
}
void MediaDecoderStateMachine::RecreateDecodedStream(int64_t aInitialTime)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
DECODER_LOG("RecreateDecodedStream aInitialTime=%lld!", aInitialTime);
mDecodedStream.RecreateData(aInitialTime, MediaStreamGraph::GetInstance());
}
} // namespace mozilla
// avoid redefined macro in unified build
+23 -2
View File
@@ -92,6 +92,7 @@ hardware (via AudioStream).
#include "mozilla/RollingMean.h"
#include "MediaTimer.h"
#include "StateMirroring.h"
#include "DecodedStream.h"
class nsITimer;
@@ -102,7 +103,6 @@ class VideoSegment;
class MediaTaskQueue;
class SharedThreadPool;
class AudioSink;
class DecodedStreamData;
class MediaDecoderStateMachineScheduler;
/*
@@ -150,7 +150,9 @@ public:
return mState;
}
void DispatchAudioCaptured();
DecodedStreamData* GetDecodedStream() const;
void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
// Check if the decoder needs to become dormant state.
bool IsDormantNeeded();
@@ -163,6 +165,8 @@ private:
// constructor immediately after the task queue is created.
void InitializationTask();
void DispatchAudioCaptured();
// Update blocking state of mDecodedStream when mPlayState or
// mLogicallySeeking change. Decoder monitor must be held.
void UpdateStreamBlockingForPlayState();
@@ -170,6 +174,12 @@ private:
// Call this IsPlaying() changes. Decoder monitor must be held.
void UpdateStreamBlockingForStateMachinePlaying();
// Recreates mDecodedStream. Call this to create mDecodedStream at first,
// and when seeking, to ensure a new stream is set up with fresh buffers.
// aInitialTime is relative to mStartTime.
// Decoder monitor must be held.
void RecreateDecodedStream(int64_t aInitialTime);
void Shutdown();
public:
@@ -326,6 +336,10 @@ public:
if (mReader) {
mReader->BreakCycles();
}
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecodedStream.DestroyData();
}
mDecoder = nullptr;
}
@@ -1257,6 +1271,13 @@ protected:
bool mSentFirstFrameLoadedEvent;
bool mSentPlaybackEndedEvent;
// The SourceMediaStream we are using to feed the mOutputStreams. This stream
// is never exposed outside the decoder.
// Only written on the main thread while holding the monitor. Therefore it
// can be read on any thread while holding the monitor, or on the main thread
// without holding the monitor.
DecodedStream mDecodedStream;
};
} // namespace mozilla;
+2 -1
View File
@@ -53,7 +53,8 @@ bool
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
{
return (mCanOffloadAudio && !mFallbackToStateMachine &&
!GetDecodedStream() && mPlaybackRate == 1.0);
!(GetStateMachine() && GetStateMachine()->GetDecodedStream()) &&
mPlaybackRate == 1.0);
}
void