зеркало из https://github.com/mozilla/gecko-dev.git
Bug 938022. Part 2: Block captured MediaStream when the MediaDecoderStateMachine is not playing. r=cpearce
--HG-- extra : rebase_source : 01d887b3b5917b7c51a286d61feb10e7b2426d9a
This commit is contained in:
Родитель
b32400571f
Коммит
397a575007
|
@ -199,7 +199,8 @@ MediaDecoder::DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder,
|
|||
mHaveSentFinishAudio(false),
|
||||
mHaveSentFinishVideo(false),
|
||||
mStream(aStream),
|
||||
mHaveBlockedForPlayState(false)
|
||||
mHaveBlockedForPlayState(false),
|
||||
mHaveBlockedForStateMachineNotPlaying(false)
|
||||
{
|
||||
mStream->AddMainThreadListener(this);
|
||||
}
|
||||
|
@ -244,6 +245,29 @@ void MediaDecoder::DestroyDecodedStream()
|
|||
mDecodedStream = nullptr;
|
||||
}
|
||||
|
||||
void MediaDecoder::UpdateStreamBlockingForStateMachinePlaying()
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
if (!mDecodedStream) {
|
||||
return;
|
||||
}
|
||||
bool blockForStateMachineNotPlaying =
|
||||
mDecoderStateMachine && !mDecoderStateMachine->IsPlaying() &&
|
||||
mDecoderStateMachine->GetState() != MediaDecoderStateMachine::DECODER_STATE_COMPLETED;
|
||||
if (blockForStateMachineNotPlaying != mDecodedStream->mHaveBlockedForStateMachineNotPlaying) {
|
||||
mDecodedStream->mHaveBlockedForStateMachineNotPlaying = blockForStateMachineNotPlaying;
|
||||
int32_t delta = blockForStateMachineNotPlaying ? 1 : -1;
|
||||
if (NS_IsMainThread()) {
|
||||
mDecodedStream->mStream->ChangeExplicitBlockerCount(delta);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableMethodWithArg<int32_t>(mDecodedStream->mStream.get(),
|
||||
&MediaStream::ChangeExplicitBlockerCount, delta);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -269,6 +293,7 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs)
|
|||
}
|
||||
ConnectDecodedStreamToOutputStream(&os);
|
||||
}
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
mDecodedStream->mHaveBlockedForPlayState = mPlayState != PLAY_STATE_PLAYING;
|
||||
if (mDecodedStream->mHaveBlockedForPlayState) {
|
||||
|
|
|
@ -384,6 +384,9 @@ public:
|
|||
// True when we've explicitly blocked this stream because we're
|
||||
// not in PLAY_STATE_PLAYING. Used on the main thread only.
|
||||
bool mHaveBlockedForPlayState;
|
||||
// We also have an explicit blocker on the stream when
|
||||
// mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
|
||||
bool mHaveBlockedForStateMachineNotPlaying;
|
||||
|
||||
virtual void NotifyMainThreadStateChanged() MOZ_OVERRIDE;
|
||||
};
|
||||
|
@ -411,8 +414,14 @@ public:
|
|||
* 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);
|
||||
/**
|
||||
* Call this when mDecoderStateMachine or mDecoderStateMachine->IsPlaying() changes.
|
||||
* Decoder monitor must be held.
|
||||
*/
|
||||
void UpdateStreamBlockingForStateMachinePlaying();
|
||||
/**
|
||||
* Called when the state of mDecodedStream as visible on the main thread
|
||||
* has changed. In particular we want to know when the stream has finished
|
||||
|
|
|
@ -1316,6 +1316,7 @@ void MediaDecoderStateMachine::StopPlayback()
|
|||
// so it can pause audio playback.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
|
||||
mDecoder->UpdateStreamBlockingForStateMachinePlaying();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::StartPlayback()
|
||||
|
@ -1333,6 +1334,7 @@ void MediaDecoderStateMachine::StartPlayback()
|
|||
NS_WARNING("Failed to create audio thread");
|
||||
}
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
mDecoder->UpdateStreamBlockingForStateMachinePlaying();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdatePlaybackPositionInternal(int64_t aTime)
|
||||
|
|
|
@ -345,6 +345,10 @@ public:
|
|||
|
||||
void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags);
|
||||
|
||||
// Returns true if we're currently playing. The decoder monitor must
|
||||
// be held.
|
||||
bool IsPlaying();
|
||||
|
||||
protected:
|
||||
virtual uint32_t GetAmpleVideoFrames() { return mAmpleVideoFrames; }
|
||||
|
||||
|
@ -519,10 +523,6 @@ private:
|
|||
|
||||
void StartDecodeMetadata();
|
||||
|
||||
// Returns true if we're currently playing. The decoder monitor must
|
||||
// be held.
|
||||
bool IsPlaying();
|
||||
|
||||
// Returns the "media time". This is the absolute time which the media
|
||||
// playback has reached. i.e. this returns values in the range
|
||||
// [mStartTime, mEndTime], and mStartTime will not be 0 if the media does
|
||||
|
|
Загрузка…
Ссылка в новой задаче