Bug 1199121. Part 2 - handle the case where audio ends before video and switch to system clock for calculating playback position. r=kinetik.

This commit is contained in:
JW Wang 2015-09-07 11:58:11 +08:00
parent 23d8116292
commit 9b07ac1bea
2 changed files with 31 additions and 3 deletions

View File

@ -83,8 +83,8 @@ AudioSinkWrapper::GetPosition(TimeStamp* aTimeStamp) const
int64_t pos = -1;
TimeStamp t = TimeStamp::Now();
if (mAudioSink) {
// Rely on the audio sink to report playback position when we have one.
if (!mAudioEnded) {
// Rely on the audio sink to report playback position when it is not ended.
pos = mAudioSink->GetPosition();
} else if (!mPlayStartTime.IsNull()) {
// Calculate playback position using system clock if we are still playing.
@ -123,7 +123,7 @@ AudioSinkWrapper::SetPlaybackRate(double aPlaybackRate)
{
AssertOwnerThread();
mParams.playbackRate = aPlaybackRate;
if (mAudioSink) {
if (!mAudioEnded) {
// Pass the playback rate to the audio sink. The underlying AudioStream
// will handle playback rate changes and report correct audio position.
mAudioSink->SetPlaybackRate(aPlaybackRate);
@ -183,10 +183,18 @@ AudioSinkWrapper::Start(int64_t aStartTime, const MediaInfo& aInfo)
mPlayDuration = aStartTime;
mPlayStartTime = TimeStamp::Now();
// no audio is equivalent to audio ended before video starts.
mAudioEnded = !aInfo.HasAudio();
if (aInfo.HasAudio()) {
mAudioSink = mCreator->Create();
mEndPromise = mAudioSink->Init();
SetPlaybackParams(mParams);
mAudioSinkPromise.Begin(mEndPromise->Then(
mOwnerThread.get(), __func__, this,
&AudioSinkWrapper::OnAudioEnded,
&AudioSinkWrapper::OnAudioEnded));
}
}
@ -197,8 +205,10 @@ AudioSinkWrapper::Stop()
MOZ_ASSERT(mIsStarted, "playback not started.");
mIsStarted = false;
mAudioEnded = true;
if (mAudioSink) {
mAudioSinkPromise.DisconnectIfExists();
mAudioSink->Shutdown();
mAudioSink = nullptr;
mEndPromise = nullptr;
@ -212,6 +222,18 @@ AudioSinkWrapper::IsStarted() const
return mIsStarted;
}
void
AudioSinkWrapper::OnAudioEnded()
{
AssertOwnerThread();
mAudioSinkPromise.Complete();
mPlayDuration = GetPosition();
if (!mPlayStartTime.IsNull()) {
mPlayStartTime = TimeStamp::Now();
}
mAudioEnded = true;
}
} // namespace media
} // namespace mozilla

View File

@ -53,6 +53,7 @@ public:
, mIsStarted(false)
// Give an insane value to facilitate debug if used before playback starts.
, mPlayDuration(INT64_MAX)
, mAudioEnded(true)
{}
const PlaybackParams& GetPlaybackParams() const override;
@ -83,6 +84,8 @@ private:
int64_t GetVideoPosition(TimeStamp aNow) const;
void OnAudioEnded();
const nsRefPtr<AbstractThread> mOwnerThread;
UniquePtr<Creator> mCreator;
nsRefPtr<AudioSink> mAudioSink;
@ -93,6 +96,9 @@ private:
TimeStamp mPlayStartTime;
int64_t mPlayDuration;
bool mAudioEnded;
MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
};
} // namespace media