зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
3fe397c6bb
Коммит
11100ac183
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче