зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f961371a5e
Коммит
7435f302de
|
@ -223,6 +223,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||||
mSentPlaybackEndedEvent(false),
|
mSentPlaybackEndedEvent(false),
|
||||||
mStreamSink(new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue)),
|
mStreamSink(new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue)),
|
||||||
mResource(aDecoder->GetResource()),
|
mResource(aDecoder->GetResource()),
|
||||||
|
mAudioOffloading(false),
|
||||||
mBuffered(mTaskQueue, TimeIntervals(),
|
mBuffered(mTaskQueue, TimeIntervals(),
|
||||||
"MediaDecoderStateMachine::mBuffered (Mirror)"),
|
"MediaDecoderStateMachine::mBuffered (Mirror)"),
|
||||||
mEstimatedDuration(mTaskQueue, NullableTimeUnit(),
|
mEstimatedDuration(mTaskQueue, NullableTimeUnit(),
|
||||||
|
@ -1088,15 +1089,13 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
|
bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
|
||||||
if (!playStatePermits || mIsAudioPrerolling || mIsVideoPrerolling) {
|
if (!playStatePermits || mIsAudioPrerolling ||
|
||||||
|
mIsVideoPrerolling || mAudioOffloading) {
|
||||||
DECODER_LOG("Not starting playback [playStatePermits: %d, "
|
DECODER_LOG("Not starting playback [playStatePermits: %d, "
|
||||||
"mIsAudioPrerolling: %d, mIsVideoPrerolling: %d]",
|
"mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, "
|
||||||
(int) playStatePermits, (int) mIsAudioPrerolling, (int) mIsVideoPrerolling);
|
"mAudioOffloading: %d]",
|
||||||
return;
|
(int)playStatePermits, (int)mIsAudioPrerolling,
|
||||||
}
|
(int)mIsVideoPrerolling, (int)mAudioOffloading);
|
||||||
|
|
||||||
if (mDecoder->CheckDecoderCanOffloadAudio()) {
|
|
||||||
DECODER_LOG("Offloading playback");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,19 @@ public:
|
||||||
OwnerThread()->Dispatch(r.forget());
|
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.
|
// Drop reference to decoder. Only called during shutdown dance.
|
||||||
void BreakCycles() {
|
void BreakCycles() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
@ -1242,6 +1255,10 @@ private:
|
||||||
MediaEventListener mAudioQueueListener;
|
MediaEventListener mAudioQueueListener;
|
||||||
MediaEventListener mVideoQueueListener;
|
MediaEventListener mVideoQueueListener;
|
||||||
|
|
||||||
|
// True if audio is offloading.
|
||||||
|
// Playback will not start when audio is offloading.
|
||||||
|
bool mAudioOffloading;
|
||||||
|
|
||||||
#ifdef MOZ_EME
|
#ifdef MOZ_EME
|
||||||
void OnCDMProxyReady(nsRefPtr<CDMProxy> aProxy);
|
void OnCDMProxyReady(nsRefPtr<CDMProxy> aProxy);
|
||||||
void OnCDMProxyNotReady();
|
void OnCDMProxyNotReady();
|
||||||
|
|
|
@ -41,13 +41,38 @@ MediaOmxCommonDecoder::~MediaOmxCommonDecoder() {}
|
||||||
void
|
void
|
||||||
MediaOmxCommonDecoder::SetPlatformCanOffloadAudio(bool aCanOffloadAudio)
|
MediaOmxCommonDecoder::SetPlatformCanOffloadAudio(bool aCanOffloadAudio)
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
if (!aCanOffloadAudio) {
|
||||||
mCanOffloadAudio = 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
|
bool
|
||||||
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
|
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
return (mCanOffloadAudio && !mFallbackToStateMachine &&
|
return (mCanOffloadAudio && !mFallbackToStateMachine &&
|
||||||
!mIsCaptured && mPlaybackRate == 1.0);
|
!mIsCaptured && mPlaybackRate == 1.0);
|
||||||
}
|
}
|
||||||
|
@ -64,10 +89,10 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||||
|
|
||||||
MediaDecoder::FirstFrameLoaded(aInfo, aEventVisibility);
|
MediaDecoder::FirstFrameLoaded(aInfo, aEventVisibility);
|
||||||
|
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
|
||||||
if (!CheckDecoderCanOffloadAudio()) {
|
if (!CheckDecoderCanOffloadAudio()) {
|
||||||
DECODER_LOG(LogLevel::Debug, ("In %s Offload Audio check failed",
|
DECODER_LOG(LogLevel::Debug, ("In %s Offload Audio check failed",
|
||||||
__PRETTY_FUNCTION__));
|
__PRETTY_FUNCTION__));
|
||||||
|
DisableStateMachineAudioOffloading();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +100,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||||
mAudioOffloadPlayer = new AudioOffloadPlayer(this);
|
mAudioOffloadPlayer = new AudioOffloadPlayer(this);
|
||||||
#endif
|
#endif
|
||||||
if (!mAudioOffloadPlayer) {
|
if (!mAudioOffloadPlayer) {
|
||||||
|
DisableStateMachineAudioOffloading();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +111,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||||
mFallbackToStateMachine = true;
|
mFallbackToStateMachine = true;
|
||||||
DECODER_LOG(LogLevel::Debug, ("In %s Unable to start offload audio %d."
|
DECODER_LOG(LogLevel::Debug, ("In %s Unable to start offload audio %d."
|
||||||
"Switching to normal mode", __PRETTY_FUNCTION__, err));
|
"Switching to normal mode", __PRETTY_FUNCTION__, err));
|
||||||
|
DisableStateMachineAudioOffloading();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PauseStateMachine();
|
PauseStateMachine();
|
||||||
|
@ -105,7 +132,6 @@ void
|
||||||
MediaOmxCommonDecoder::PauseStateMachine()
|
MediaOmxCommonDecoder::PauseStateMachine()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
|
||||||
DECODER_LOG(LogLevel::Debug, ("%s", __PRETTY_FUNCTION__));
|
DECODER_LOG(LogLevel::Debug, ("%s", __PRETTY_FUNCTION__));
|
||||||
|
|
||||||
if (mShuttingDown) {
|
if (mShuttingDown) {
|
||||||
|
@ -123,7 +149,6 @@ void
|
||||||
MediaOmxCommonDecoder::ResumeStateMachine()
|
MediaOmxCommonDecoder::ResumeStateMachine()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
|
||||||
DECODER_LOG(LogLevel::Debug, ("%s current time %f", __PRETTY_FUNCTION__, mLogicalPosition));
|
DECODER_LOG(LogLevel::Debug, ("%s current time %f", __PRETTY_FUNCTION__, mLogicalPosition));
|
||||||
|
|
||||||
if (mShuttingDown) {
|
if (mShuttingDown) {
|
||||||
|
@ -134,6 +159,8 @@ MediaOmxCommonDecoder::ResumeStateMachine()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetStateMachine()->DispatchAudioOffloading(false);
|
||||||
|
|
||||||
mFallbackToStateMachine = true;
|
mFallbackToStateMachine = true;
|
||||||
mAudioOffloadPlayer = nullptr;
|
mAudioOffloadPlayer = nullptr;
|
||||||
SeekTarget target = SeekTarget(mLogicalPosition,
|
SeekTarget target = SeekTarget(mLogicalPosition,
|
||||||
|
@ -231,8 +258,6 @@ MediaOmxCommonDecoder::CurrentPosition()
|
||||||
if (!mAudioOffloadPlayer) {
|
if (!mAudioOffloadPlayer) {
|
||||||
return MediaDecoder::CurrentPosition();
|
return MediaDecoder::CurrentPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
|
||||||
return mAudioOffloadPlayer->GetMediaTimeUs();
|
return mAudioOffloadPlayer->GetMediaTimeUs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ protected:
|
||||||
virtual ~MediaOmxCommonDecoder();
|
virtual ~MediaOmxCommonDecoder();
|
||||||
void PauseStateMachine();
|
void PauseStateMachine();
|
||||||
void ResumeStateMachine();
|
void ResumeStateMachine();
|
||||||
|
void DisableStateMachineAudioOffloading();
|
||||||
|
|
||||||
MediaOmxCommonReader* mReader;
|
MediaOmxCommonReader* mReader;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче