// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "media/base/wall_clock_time_source.h" #include "base/logging.h" namespace media { WallClockTimeSource::WallClockTimeSource() : tick_clock_(&default_tick_clock_), ticking_(false), playback_rate_(1.0) { } WallClockTimeSource::~WallClockTimeSource() { } void WallClockTimeSource::StartTicking() { DVLOG(1) << __FUNCTION__; base::AutoLock auto_lock(lock_); DCHECK(!ticking_); ticking_ = true; reference_time_ = tick_clock_->NowTicks(); } void WallClockTimeSource::StopTicking() { DVLOG(1) << __FUNCTION__; base::AutoLock auto_lock(lock_); DCHECK(ticking_); base_timestamp_ = CurrentMediaTime_Locked(); ticking_ = false; reference_time_ = tick_clock_->NowTicks(); } void WallClockTimeSource::SetPlaybackRate(double playback_rate) { DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; base::AutoLock auto_lock(lock_); // Estimate current media time using old rate to use as a new base time for // the new rate. if (ticking_) { base_timestamp_ = CurrentMediaTime_Locked(); reference_time_ = tick_clock_->NowTicks(); } playback_rate_ = playback_rate; } void WallClockTimeSource::SetMediaTime(base::TimeDelta time) { DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")"; base::AutoLock auto_lock(lock_); CHECK(!ticking_); base_timestamp_ = time; } base::TimeDelta WallClockTimeSource::CurrentMediaTime() { base::AutoLock auto_lock(lock_); return CurrentMediaTime_Locked(); } bool WallClockTimeSource::GetWallClockTimes( const std::vector& media_timestamps, std::vector* wall_clock_times) { base::AutoLock auto_lock(lock_); DCHECK(wall_clock_times->empty()); if (media_timestamps.empty()) { wall_clock_times->push_back(reference_time_); } else { // When playback is paused (rate is zero), assume a rate of 1.0. const double playback_rate = playback_rate_ ? playback_rate_ : 1.0; wall_clock_times->reserve(media_timestamps.size()); for (const auto& media_timestamp : media_timestamps) { wall_clock_times->push_back(reference_time_ + (media_timestamp - base_timestamp_) / playback_rate); } } return playback_rate_ && ticking_; } base::TimeDelta WallClockTimeSource::CurrentMediaTime_Locked() { lock_.AssertAcquired(); if (!ticking_ || !playback_rate_) return base_timestamp_; base::TimeTicks now = tick_clock_->NowTicks(); return base_timestamp_ + base::TimeDelta::FromMicroseconds( (now - reference_time_).InMicroseconds() * playback_rate_); } } // namespace media