mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
Rework MediaDecoder::AddOutputStream and move related code to the MDSM
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -53,7 +53,8 @@ bool
|
||||
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
|
||||
{
|
||||
return (mCanOffloadAudio && !mFallbackToStateMachine &&
|
||||
!GetDecodedStream() && mPlaybackRate == 1.0);
|
||||
!(GetStateMachine() && GetStateMachine()->GetDecodedStream()) &&
|
||||
mPlaybackRate == 1.0);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user