Bug 1496281 - let AudioSinkWrapper decide whether we need to create AudioSink. r=jya

Allow AudioSinkWrapper to access MDSM's audio queue in order to know whether the audio source ended.

Differential Revision: https://phabricator.services.mozilla.com/D8031

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2018-10-19 23:30:06 +00:00
parent 8a334bc798
commit b020b31588
3 changed files with 25 additions and 7 deletions

View File

@ -2787,7 +2787,7 @@ MediaDecoderStateMachine::CreateAudioSink()
&MediaDecoderStateMachine::AudioAudibleChanged);
return audioSink;
};
return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
return new AudioSinkWrapper(mTaskQueue, mAudioQueue, audioSinkCreator);
}
already_AddRefed<media::MediaSink>

View File

@ -86,6 +86,7 @@ AudioSinkWrapper::GetPosition(TimeStamp* aTimeStamp) const
TimeStamp t = TimeStamp::Now();
if (!mAudioEnded) {
MOZ_ASSERT(mAudioSink);
// Rely on the audio sink to report playback position when it is not ended.
pos = mAudioSink->GetPosition();
} else if (!mPlayStartTime.IsNull()) {
@ -187,24 +188,34 @@ AudioSinkWrapper::Start(const TimeUnit& aStartTime, const MediaInfo& aInfo)
mIsStarted = true;
mPlayDuration = aStartTime;
mPlayStartTime = TimeStamp::Now();
// no audio is equivalent to audio ended before video starts.
mAudioEnded = !aInfo.HasAudio();
mAudioEnded = IsAudioSourceEnded(aInfo);
nsresult rv = NS_OK;
if (aInfo.HasAudio()) {
if (!mAudioEnded) {
mAudioSink.reset(mCreator->Create());
rv = mAudioSink->Init(mParams, mEndPromise);
mEndPromise->Then(
mOwnerThread.get(), __func__, this,
&AudioSinkWrapper::OnAudioEnded,
&AudioSinkWrapper::OnAudioEnded
)->Track(mAudioSinkPromise);
} else {
if (aInfo.HasAudio()) {
mEndPromise = GenericPromise::CreateAndResolve(true, __func__);
}
}
return rv;
}
bool
AudioSinkWrapper::IsAudioSourceEnded(const MediaInfo& aInfo) const
{
// no audio or empty audio queue which won't get data anymore is equivalent to
// audio ended
return !aInfo.HasAudio() ||
(mAudioQueue.IsFinished() && mAudioQueue.GetSize() == 0u);
}
void
AudioSinkWrapper::Stop()
{

View File

@ -45,13 +45,16 @@ class AudioSinkWrapper : public MediaSink {
public:
template <typename Function>
AudioSinkWrapper(AbstractThread* aOwnerThread, const Function& aFunc)
AudioSinkWrapper(AbstractThread* aOwnerThread,
const MediaQueue<AudioData>& aAudioQueue,
const Function& aFunc)
: mOwnerThread(aOwnerThread)
, mCreator(new CreatorImpl<Function>(aFunc))
, mIsStarted(false)
// Give an invalid value to facilitate debug if used before playback starts.
, mPlayDuration(TimeUnit::Invalid())
, mAudioEnded(true)
, mAudioQueue(aAudioQueue)
{}
const PlaybackParams& GetPlaybackParams() const override;
@ -87,9 +90,12 @@ private:
void OnAudioEnded();
bool IsAudioSourceEnded(const MediaInfo& aInfo) const;
const RefPtr<AbstractThread> mOwnerThread;
UniquePtr<Creator> mCreator;
UniquePtr<AudioSink> mAudioSink;
// Will only exist when media has an audio track.
RefPtr<GenericPromise> mEndPromise;
bool mIsStarted;
@ -100,6 +106,7 @@ private:
bool mAudioEnded;
MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
const MediaQueue<AudioData>& mAudioQueue;
};
} // namespace media