--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -483,18 +483,18 @@ public:
void Enter()
{
if (mMaster->IsPlaying()) {
mMaster->StopPlayback();
}
// Calculate the position to seek to when exiting dormant.
- auto t = mMaster->mMediaSink->IsStarted() ? mMaster->GetClock()
- : mMaster->GetMediaTime();
+ auto t = mMaster->mMediaSink->IsStarted()
+ ? mMaster->GetClock() : mMaster->GetMediaTime().ToMicroseconds();
mPendingSeek.mTarget.emplace(t, SeekTarget::Accurate);
// SeekJob asserts |mTarget.IsValid() == !mPromise.IsEmpty()| so we
// need to create the promise even it is not used at all.
RefPtr<MediaDecoder::SeekPromise> x =
mPendingSeek.mPromise.Ensure(__func__);
mMaster->ResetDecode();
mMaster->StopMediaSink();
@@ -722,18 +722,17 @@ public:
void HandleAudioCanceled() override
{
mMaster->RequestAudioData();
}
void HandleVideoCanceled() override
{
mMaster->RequestVideoData(
- NeedToSkipToNextKeyframe(),
- media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+ NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
}
void HandleEndOfAudio() override;
void HandleEndOfVideo() override;
void HandleWaitingForAudio() override
{
mMaster->WaitForData(MediaData::AUDIO_DATA);
@@ -749,18 +748,17 @@ public:
void HandleAudioWaited(MediaData::Type aType) override
{
mMaster->RequestAudioData();
}
void HandleVideoWaited(MediaData::Type aType) override
{
mMaster->RequestVideoData(
- NeedToSkipToNextKeyframe(),
- media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+ NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
}
void HandleAudioCaptured() override
{
MaybeStopPrerolling();
// MediaSink is changed. Schedule Step() to check if we can start playback.
mMaster->ScheduleStateMachine();
}
@@ -1023,18 +1021,17 @@ public:
explicit AccurateSeekingState(Master* aPtr) : SeekingState(aPtr)
{
}
RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob&& aSeekJob,
EventVisibility aVisibility)
{
MOZ_ASSERT(aSeekJob.mTarget->IsAccurate() || aSeekJob.mTarget->IsFast());
- mCurrentTimeBeforeSeek =
- TimeUnit::FromMicroseconds(mMaster->GetMediaTime());
+ mCurrentTimeBeforeSeek = mMaster->GetMediaTime();
return SeekingState::Enter(Move(aSeekJob), aVisibility);
}
void Exit() override
{
// Disconnect MediaDecoder.
mSeekJob.RejectIfExists(__func__);
@@ -1482,17 +1479,17 @@ public:
explicit NextFrameSeekingState(Master* aPtr) : SeekingState(aPtr)
{
}
RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob&& aSeekJob,
EventVisibility aVisibility)
{
MOZ_ASSERT(aSeekJob.mTarget->IsNextFrame());
- mCurrentTime = mMaster->GetMediaTime();
+ mCurrentTime = mMaster->GetMediaTime().ToMicroseconds();
mDuration = mMaster->Duration();
return SeekingState::Enter(Move(aSeekJob), aVisibility);
}
void Exit() override
{
// Disconnect my async seek operation.
mAsyncSeekTask->Cancel();
@@ -2280,18 +2277,17 @@ MediaDecoderStateMachine::
DecodingState::EnsureVideoDecodeTaskQueued()
{
if (!mMaster->IsVideoDecoding()
|| mMaster->IsRequestingVideoData()
|| mMaster->IsWaitingVideoData()) {
return;
}
mMaster->RequestVideoData(
- NeedToSkipToNextKeyframe(),
- media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+ NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
}
bool
MediaDecoderStateMachine::
DecodingState::NeedToSkipToNextKeyframe()
{
// Since GetClock() can only be called after starting MediaSink, we return
// false quickly if it is not started because we won't fall behind playback
@@ -2722,17 +2718,17 @@ MediaDecoderStateMachine::AudioAudibleCh
media::MediaSink*
MediaDecoderStateMachine::CreateAudioSink()
{
RefPtr<MediaDecoderStateMachine> self = this;
auto audioSinkCreator = [self] () {
MOZ_ASSERT(self->OnTaskQueue());
AudioSink* audioSink = new AudioSink(
self->mTaskQueue, self->mAudioQueue,
- TimeUnit::FromMicroseconds(self->GetMediaTime()),
+ self->GetMediaTime(),
self->Info().mAudio, self->mAudioChannel);
self->mAudibleListener = audioSink->AudibleEvent().Connect(
self->mTaskQueue, self.get(),
&MediaDecoderStateMachine::AudioAudibleChanged);
return audioSink;
};
return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
@@ -2926,18 +2922,18 @@ MediaDecoderStateMachine::UpdatePlayback
}
void
MediaDecoderStateMachine::UpdatePlaybackPosition(const TimeUnit& aTime)
{
MOZ_ASSERT(OnTaskQueue());
UpdatePlaybackPositionInternal(aTime);
- bool fragmentEnded =
- mFragmentEndTime >= 0 && GetMediaTime() >= mFragmentEndTime;
+ bool fragmentEnded = mFragmentEndTime >= 0
+ && GetMediaTime().ToMicroseconds() >= mFragmentEndTime;
mMetadataManager.DispatchMetadataIfNeeded(aTime);
if (fragmentEnded) {
StopPlayback();
}
}
/* static */ const char*
@@ -3272,17 +3268,17 @@ MediaDecoderStateMachine::WaitForData(Me
}
void
MediaDecoderStateMachine::StartMediaSink()
{
MOZ_ASSERT(OnTaskQueue());
if (!mMediaSink->IsStarted()) {
mAudioCompleted = false;
- mMediaSink->Start(TimeUnit::FromMicroseconds(GetMediaTime()), Info());
+ mMediaSink->Start(GetMediaTime(), Info());
auto videoPromise = mMediaSink->OnEnded(TrackInfo::kVideoTrack);
auto audioPromise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
if (audioPromise) {
audioPromise->Then(
OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnMediaSinkAudioComplete,
@@ -3371,18 +3367,17 @@ MediaDecoderStateMachine::HasLowBuffered
}
if (endOfDecodedData.IsInfinite()) {
// Have decoded all samples. No point buffering.
return false;
}
auto start = endOfDecodedData;
- auto end = std::min(
- TimeUnit::FromMicroseconds(GetMediaTime()) + aThreshold, Duration());
+ auto end = std::min(GetMediaTime() + aThreshold, Duration());
if (start >= end) {
// Duration of decoded samples is greater than our threshold.
return false;
}
media::TimeInterval interval(start, end);
return !mBuffered.Ref().Contains(interval);
}
@@ -3498,49 +3493,49 @@ MediaDecoderStateMachine::ResetDecode(Tr
mReader->ResetDecode(aTracks);
}
int64_t
MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
{
MOZ_ASSERT(OnTaskQueue());
- int64_t clockTime = mMediaSink->GetPosition(aTimeStamp).ToMicroseconds();
+ auto clockTime = mMediaSink->GetPosition(aTimeStamp);
NS_ASSERTION(GetMediaTime() <= clockTime, "Clock should go forwards.");
- return clockTime;
+ return clockTime.ToMicroseconds();
}
void
MediaDecoderStateMachine::UpdatePlaybackPositionPeriodically()
{
MOZ_ASSERT(OnTaskQueue());
if (!IsPlaying()) {
return;
}
// Cap the current time to the larger of the audio and video end time.
// This ensures that if we're running off the system clock, we don't
// advance the clock to after the media end time.
if (VideoEndTime() > TimeUnit::Zero() || AudioEndTime() > TimeUnit::Zero()) {
- const int64_t clockTime = GetClock();
+ const auto clockTime = TimeUnit::FromMicroseconds(GetClock());
// Skip frames up to the frame at the playback position, and figure out
// the time remaining until it's time to display the next frame and drop
// the current frame.
- NS_ASSERTION(clockTime >= 0, "Should have positive clock time.");
+ NS_ASSERTION(clockTime >= TimeUnit::Zero(), "Should have positive clock time.");
// These will be non -1 if we've displayed a video frame, or played an audio
// frame.
auto maxEndTime = std::max(VideoEndTime(), AudioEndTime());
- int64_t t = std::min(clockTime, maxEndTime.ToMicroseconds());
+ auto t = std::min(clockTime, maxEndTime);
// FIXME: Bug 1091422 - chained ogg files hit this assertion.
//MOZ_ASSERT(t >= GetMediaTime());
if (t > GetMediaTime()) {
- UpdatePlaybackPosition(TimeUnit::FromMicroseconds(t));
+ UpdatePlaybackPosition(t);
}
}
// Note we have to update playback position before releasing the monitor.
// Otherwise, MediaDecoder::AddOutputStream could kick in when we are outside
// the monitor and get a staled value from GetCurrentTimeUs() which hits the
// assertion in GetClock().
int64_t delay = std::max<int64_t>(1, AUDIO_DURATION_USECS / mPlaybackRate);
@@ -3829,17 +3824,18 @@ MediaDecoderStateMachine::GetDebugInfo()
MOZ_ASSERT(OnTaskQueue());
return nsPrintfCString(
"MediaDecoderStateMachine State: GetMediaTime=%" PRId64 " GetClock="
"%" PRId64 " mMediaSink=%p state=%s mPlayState=%d "
"mSentFirstFrameLoadedEvent=%d IsPlaying=%d mAudioStatus=%s "
"mVideoStatus=%s mDecodedAudioEndTime=%" PRId64
" mDecodedVideoEndTime=%" PRId64 "mAudioCompleted=%d "
"mVideoCompleted=%d",
- GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1,
+ GetMediaTime().ToMicroseconds(),
+ mMediaSink->IsStarted() ? GetClock() : -1,
mMediaSink.get(), ToStateStr(), mPlayState.Ref(),
mSentFirstFrameLoadedEvent, IsPlaying(), AudioRequestStatus(),
VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
mAudioCompleted, mVideoCompleted)
+ mStateObj->GetDebugInfo() + nsCString("\n")
+ mMediaSink->GetDebugInfo();
}
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -443,20 +443,20 @@ protected:
bool IsWaitingAudioData() const { return mAudioWaitRequest.Exists(); }
bool IsWaitingVideoData() const { return mVideoWaitRequest.Exists(); }
// Returns the "media time". This is the absolute time which the media
// playback has reached. i.e. this returns values in the range
// [mStartTime, mEndTime], and mStartTime will not be 0 if the media does
// not start at 0. Note this is different than the "current playback position",
// which is in the range [0,duration].
- int64_t GetMediaTime() const
+ media::TimeUnit GetMediaTime() const
{
MOZ_ASSERT(OnTaskQueue());
- return mCurrentPosition;
+ return media::TimeUnit::FromMicroseconds(mCurrentPosition.Ref());
}
// Returns an upper bound on the number of microseconds of audio that is
// decoded and playable. This is the sum of the number of usecs of audio which
// is decoded and in the reader's audio queue, and the usecs of unplayed audio
// which has been pushed to the audio hardware for playback. Note that after
// calling this, the audio hardware may play some of the audio pushed to
// hardware, so this can only be used as a upper bound. The decoder monitor