зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1186801 - Remove decoder monitor from AudioSink. r=kinetik.
This commit is contained in:
Родитель
8942b13e62
Коммит
6417ed4d21
|
@ -23,12 +23,11 @@ extern PRLogModuleInfo* gMediaDecoderLog;
|
|||
static const int64_t AUDIO_FUZZ_FRAMES = 1;
|
||||
|
||||
AudioSink::AudioSink(MediaQueue<AudioData>& aAudioQueue,
|
||||
ReentrantMonitor& aMonitor,
|
||||
int64_t aStartTime,
|
||||
const AudioInfo& aInfo,
|
||||
dom::AudioChannel aChannel)
|
||||
: mAudioQueue(aAudioQueue)
|
||||
, mDecoderMonitor(aMonitor)
|
||||
, mMonitor("AudioSink::mMonitor")
|
||||
, mStartTime(aStartTime)
|
||||
, mWritten(0)
|
||||
, mLastGoodPosition(0)
|
||||
|
@ -71,7 +70,7 @@ AudioSink::Init()
|
|||
int64_t
|
||||
AudioSink::GetPosition()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
int64_t pos;
|
||||
if (mAudioStream &&
|
||||
|
@ -86,7 +85,7 @@ AudioSink::GetPosition()
|
|||
bool
|
||||
AudioSink::HasUnplayedFrames()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
// Experimentation suggests that GetPositionInFrames() is zero-indexed,
|
||||
// so we need to add 1 here before comparing it to mWritten.
|
||||
return mAudioStream && mAudioStream->GetPositionInFrames() + 1 < mWritten;
|
||||
|
@ -95,13 +94,14 @@ AudioSink::HasUnplayedFrames()
|
|||
void
|
||||
AudioSink::Shutdown()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mStopAudioThread = true;
|
||||
if (mAudioStream) {
|
||||
mAudioStream->Cancel();
|
||||
}
|
||||
GetReentrantMonitor().NotifyAll();
|
||||
|
||||
// Exit the monitor so audio loop can enter the monitor and finish its job.
|
||||
ReentrantMonitorAutoExit exit(GetReentrantMonitor());
|
||||
mThread->Shutdown();
|
||||
mThread = nullptr;
|
||||
|
@ -114,7 +114,7 @@ AudioSink::Shutdown()
|
|||
void
|
||||
AudioSink::SetVolume(double aVolume)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mVolume = aVolume;
|
||||
mSetVolume = true;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ AudioSink::SetVolume(double aVolume)
|
|||
void
|
||||
AudioSink::SetPlaybackRate(double aPlaybackRate)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
NS_ASSERTION(mPlaybackRate != 0, "Don't set the playbackRate to 0 on AudioStream");
|
||||
mPlaybackRate = aPlaybackRate;
|
||||
mSetPlaybackRate = true;
|
||||
|
@ -131,7 +131,7 @@ AudioSink::SetPlaybackRate(double aPlaybackRate)
|
|||
void
|
||||
AudioSink::SetPreservesPitch(bool aPreservesPitch)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mPreservesPitch = aPreservesPitch;
|
||||
mSetPreservesPitch = true;
|
||||
}
|
||||
|
@ -139,11 +139,18 @@ AudioSink::SetPreservesPitch(bool aPreservesPitch)
|
|||
void
|
||||
AudioSink::SetPlaying(bool aPlaying)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mPlaying = aPlaying;
|
||||
GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
AudioSink::NotifyData()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
AudioSink::AudioLoop()
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioSink)
|
||||
|
||||
AudioSink(MediaQueue<AudioData>& aAudioQueue,
|
||||
ReentrantMonitor& aMonitor,
|
||||
int64_t aStartTime,
|
||||
const AudioInfo& aInfo,
|
||||
dom::AudioChannel aChannel);
|
||||
|
@ -35,9 +34,10 @@ public:
|
|||
// or rejected if any error.
|
||||
nsRefPtr<GenericPromise> Init();
|
||||
|
||||
/*
|
||||
* All public functions below are thread-safe.
|
||||
*/
|
||||
int64_t GetPosition();
|
||||
|
||||
// Thread-safe. Can be called on any thread.
|
||||
int64_t GetEndTime() const;
|
||||
|
||||
// Check whether we've pushed more frames to the audio hardware than it has
|
||||
|
@ -45,15 +45,17 @@ public:
|
|||
bool HasUnplayedFrames();
|
||||
|
||||
// Shut down the AudioSink's resources.
|
||||
// Must be called with the decoder monitor held.
|
||||
void Shutdown();
|
||||
|
||||
void SetVolume(double aVolume);
|
||||
void SetPlaybackRate(double aPlaybackRate);
|
||||
void SetPreservesPitch(bool aPreservesPitch);
|
||||
|
||||
void SetPlaying(bool aPlaying);
|
||||
|
||||
// Wake up the audio loop if it is waiting for data to play or the audio
|
||||
// queue is finished.
|
||||
void NotifyData();
|
||||
|
||||
private:
|
||||
~AudioSink() {}
|
||||
|
||||
|
@ -104,7 +106,7 @@ private:
|
|||
}
|
||||
|
||||
ReentrantMonitor& GetReentrantMonitor() const {
|
||||
return mDecoderMonitor;
|
||||
return mMonitor;
|
||||
}
|
||||
|
||||
void AssertCurrentThreadInMonitor() const {
|
||||
|
@ -114,7 +116,7 @@ private:
|
|||
void AssertOnAudioThread();
|
||||
|
||||
MediaQueue<AudioData>& mAudioQueue;
|
||||
ReentrantMonitor& mDecoderMonitor;
|
||||
mutable ReentrantMonitor mMonitor;
|
||||
|
||||
// Thread for pushing audio onto the audio hardware.
|
||||
// The "audio push thread".
|
||||
|
|
|
@ -642,8 +642,9 @@ MediaDecoderStateMachine::Push(AudioData* aSample)
|
|||
UpdateNextFrameStatus();
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
|
||||
// XXXbholley - Still necessary?
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
if (mAudioSink) {
|
||||
mAudioSink->NotifyData();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -789,6 +790,10 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
|||
case DECODER_STATE_DECODING: {
|
||||
CheckIfDecodeComplete();
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
// Tell AudioSink to wake up for audio queue is finished.
|
||||
if (mAudioSink) {
|
||||
mAudioSink->NotifyData();
|
||||
}
|
||||
// Schedule the state machine to notify track ended as soon as possible.
|
||||
if (mAudioCaptured) {
|
||||
ScheduleStateMachine();
|
||||
|
@ -1053,9 +1058,6 @@ void MediaDecoderStateMachine::StopPlayback()
|
|||
mPlayDuration = GetClock();
|
||||
SetPlayStartTime(TimeStamp());
|
||||
}
|
||||
// Notify the audio sink, so that it notices that we've stopped playing,
|
||||
// so it can pause audio playback.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
|
||||
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
|
@ -1794,7 +1796,7 @@ MediaDecoderStateMachine::StartAudioThread()
|
|||
|
||||
if (HasAudio() && !mAudioSink) {
|
||||
mAudioCompleted = false;
|
||||
mAudioSink = new AudioSink(mAudioQueue, mDecoder->GetReentrantMonitor(),
|
||||
mAudioSink = new AudioSink(mAudioQueue,
|
||||
GetMediaTime(), mInfo.mAudio,
|
||||
mDecoder->GetAudioChannel());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче