Commit 465cf3e6 authored by scherkus's avatar scherkus Committed by Commit bot

Make media::WallClockTimeSource thread safe.

Temporary measure until both Pipeline is reworked to provide a time
estimate to the main thread and VideoRendererImpl's internal thread
is eliminated.

This is similar to the the locking currently present in
AudioRendererImpl.

BUG=412764

Review URL: https://codereview.chromium.org/562673003

Cr-Commit-Position: refs/heads/master@{#294207}
parent 947fb1c4
......@@ -301,9 +301,6 @@ char kTSanDefaultSuppressions[] =
"deadlock:"
"base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"
// http://crbug.com/412764
"race:media::WallClockTimeSource::SetPlaybackRate\n"
// End of suppressions.
; // Please keep this semicolon.
......
......@@ -19,23 +19,26 @@ WallClockTimeSource::~WallClockTimeSource() {
}
void WallClockTimeSource::StartTicking() {
base::AutoLock auto_lock(lock_);
DCHECK(!ticking_);
ticking_ = true;
reference_wall_ticks_ = tick_clock_->NowTicks();
}
void WallClockTimeSource::StopTicking() {
base::AutoLock auto_lock(lock_);
DCHECK(ticking_);
base_time_ = CurrentMediaTime();
base_time_ = CurrentMediaTime_Locked();
ticking_ = false;
reference_wall_ticks_ = tick_clock_->NowTicks();
}
void WallClockTimeSource::SetPlaybackRate(float 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_time_ = CurrentMediaTime();
base_time_ = CurrentMediaTime_Locked();
reference_wall_ticks_ = tick_clock_->NowTicks();
}
......@@ -43,18 +46,14 @@ void WallClockTimeSource::SetPlaybackRate(float playback_rate) {
}
void WallClockTimeSource::SetMediaTime(base::TimeDelta time) {
base::AutoLock auto_lock(lock_);
CHECK(!ticking_);
base_time_ = time;
}
base::TimeDelta WallClockTimeSource::CurrentMediaTime() {
if (!ticking_)
return base_time_;
base::TimeTicks now = tick_clock_->NowTicks();
return base_time_ +
base::TimeDelta::FromMicroseconds(
(now - reference_wall_ticks_).InMicroseconds() * playback_rate_);
base::AutoLock auto_lock(lock_);
return CurrentMediaTime_Locked();
}
base::TimeDelta WallClockTimeSource::CurrentMediaTimeForSyncingVideo() {
......@@ -66,4 +65,15 @@ void WallClockTimeSource::SetTickClockForTesting(
tick_clock_.swap(tick_clock);
}
base::TimeDelta WallClockTimeSource::CurrentMediaTime_Locked() {
lock_.AssertAcquired();
if (!ticking_)
return base_time_;
base::TimeTicks now = tick_clock_->NowTicks();
return base_time_ +
base::TimeDelta::FromMicroseconds(
(now - reference_wall_ticks_).InMicroseconds() * playback_rate_);
}
} // namespace media
......@@ -6,6 +6,7 @@
#define MEDIA_BASE_WALL_CLOCK_TIME_SOURCE_H_
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
#include "media/base/time_source.h"
......@@ -32,6 +33,8 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource {
void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock);
private:
base::TimeDelta CurrentMediaTime_Locked();
scoped_ptr<base::TickClock> tick_clock_;
bool ticking_;
......@@ -42,6 +45,10 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource {
base::TimeDelta base_time_;
base::TimeTicks reference_wall_ticks_;
// TODO(scherkus): Remove internal locking from this class after access to
// Renderer::CurrentMediaTime() is single threaded http://crbug.com/370634
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(WallClockTimeSource);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment