Bug 1209864. Part 1 - make all methods run on the main thread and remove usage of the decoder monitor. r=roc.

This commit is contained in:
JW Wang 2015-09-27 21:37:48 +08:00
Родитель f961371a5e
Коммит 7435f302de
4 изменённых файлов: 57 добавлений и 15 удалений

Просмотреть файл

@ -223,6 +223,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mSentPlaybackEndedEvent(false),
mStreamSink(new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue)),
mResource(aDecoder->GetResource()),
mAudioOffloading(false),
mBuffered(mTaskQueue, TimeIntervals(),
"MediaDecoderStateMachine::mBuffered (Mirror)"),
mEstimatedDuration(mTaskQueue, NullableTimeUnit(),
@ -1088,15 +1089,13 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
}
bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
if (!playStatePermits || mIsAudioPrerolling || mIsVideoPrerolling) {
if (!playStatePermits || mIsAudioPrerolling ||
mIsVideoPrerolling || mAudioOffloading) {
DECODER_LOG("Not starting playback [playStatePermits: %d, "
"mIsAudioPrerolling: %d, mIsVideoPrerolling: %d]",
(int) playStatePermits, (int) mIsAudioPrerolling, (int) mIsVideoPrerolling);
return;
}
if (mDecoder->CheckDecoderCanOffloadAudio()) {
DECODER_LOG("Offloading playback");
"mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, "
"mAudioOffloading: %d]",
(int)playStatePermits, (int)mIsAudioPrerolling,
(int)mIsVideoPrerolling, (int)mAudioOffloading);
return;
}

Просмотреть файл

@ -205,6 +205,19 @@ public:
OwnerThread()->Dispatch(r.forget());
}
void DispatchAudioOffloading(bool aAudioOffloading)
{
nsRefPtr<MediaDecoderStateMachine> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
if (self->mAudioOffloading != aAudioOffloading) {
self->mAudioOffloading = aAudioOffloading;
self->ScheduleStateMachine();
}
});
OwnerThread()->Dispatch(r.forget());
}
// Drop reference to decoder. Only called during shutdown dance.
void BreakCycles() {
MOZ_ASSERT(NS_IsMainThread());
@ -1242,6 +1255,10 @@ private:
MediaEventListener mAudioQueueListener;
MediaEventListener mVideoQueueListener;
// True if audio is offloading.
// Playback will not start when audio is offloading.
bool mAudioOffloading;
#ifdef MOZ_EME
void OnCDMProxyReady(nsRefPtr<CDMProxy> aProxy);
void OnCDMProxyNotReady();

Просмотреть файл

@ -41,13 +41,38 @@ MediaOmxCommonDecoder::~MediaOmxCommonDecoder() {}
void
MediaOmxCommonDecoder::SetPlatformCanOffloadAudio(bool aCanOffloadAudio)
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mCanOffloadAudio = aCanOffloadAudio;
if (!aCanOffloadAudio) {
return;
}
// Stop MDSM from playing to avoid startup glitch (bug 1053186).
GetStateMachine()->DispatchAudioOffloading(true);
// Modify mCanOffloadAudio in the main thread.
nsRefPtr<MediaOmxCommonDecoder> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
self->mCanOffloadAudio = true;
});
AbstractThread::MainThread()->Dispatch(r.forget());
}
void
MediaOmxCommonDecoder::DisableStateMachineAudioOffloading()
{
MOZ_ASSERT(NS_IsMainThread());
if (mCanOffloadAudio) {
// mCanOffloadAudio is true implies we've called
// |GetStateMachine()->DispatchAudioOffloading(true)| in
// SetPlatformCanOffloadAudio(). We need to turn off audio offloading
// for MDSM so it can start playback.
GetStateMachine()->DispatchAudioOffloading(false);
}
}
bool
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
{
MOZ_ASSERT(NS_IsMainThread());
return (mCanOffloadAudio && !mFallbackToStateMachine &&
!mIsCaptured && mPlaybackRate == 1.0);
}
@ -64,10 +89,10 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoder::FirstFrameLoaded(aInfo, aEventVisibility);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!CheckDecoderCanOffloadAudio()) {
DECODER_LOG(LogLevel::Debug, ("In %s Offload Audio check failed",
__PRETTY_FUNCTION__));
DisableStateMachineAudioOffloading();
return;
}
@ -75,6 +100,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
mAudioOffloadPlayer = new AudioOffloadPlayer(this);
#endif
if (!mAudioOffloadPlayer) {
DisableStateMachineAudioOffloading();
return;
}
@ -85,6 +111,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
mFallbackToStateMachine = true;
DECODER_LOG(LogLevel::Debug, ("In %s Unable to start offload audio %d."
"Switching to normal mode", __PRETTY_FUNCTION__, err));
DisableStateMachineAudioOffloading();
return;
}
PauseStateMachine();
@ -105,7 +132,6 @@ void
MediaOmxCommonDecoder::PauseStateMachine()
{
MOZ_ASSERT(NS_IsMainThread());
GetReentrantMonitor().AssertCurrentThreadIn();
DECODER_LOG(LogLevel::Debug, ("%s", __PRETTY_FUNCTION__));
if (mShuttingDown) {
@ -123,7 +149,6 @@ void
MediaOmxCommonDecoder::ResumeStateMachine()
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
DECODER_LOG(LogLevel::Debug, ("%s current time %f", __PRETTY_FUNCTION__, mLogicalPosition));
if (mShuttingDown) {
@ -134,6 +159,8 @@ MediaOmxCommonDecoder::ResumeStateMachine()
return;
}
GetStateMachine()->DispatchAudioOffloading(false);
mFallbackToStateMachine = true;
mAudioOffloadPlayer = nullptr;
SeekTarget target = SeekTarget(mLogicalPosition,
@ -231,8 +258,6 @@ MediaOmxCommonDecoder::CurrentPosition()
if (!mAudioOffloadPlayer) {
return MediaDecoder::CurrentPosition();
}
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
return mAudioOffloadPlayer->GetMediaTimeUs();
}

Просмотреть файл

@ -50,6 +50,7 @@ protected:
virtual ~MediaOmxCommonDecoder();
void PauseStateMachine();
void ResumeStateMachine();
void DisableStateMachineAudioOffloading();
MediaOmxCommonReader* mReader;