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[] = ...@@ -301,9 +301,6 @@ char kTSanDefaultSuppressions[] =
"deadlock:" "deadlock:"
"base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n" "base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"
// http://crbug.com/412764
"race:media::WallClockTimeSource::SetPlaybackRate\n"
// End of suppressions. // End of suppressions.
; // Please keep this semicolon. ; // Please keep this semicolon.
......
...@@ -19,23 +19,26 @@ WallClockTimeSource::~WallClockTimeSource() { ...@@ -19,23 +19,26 @@ WallClockTimeSource::~WallClockTimeSource() {
} }
void WallClockTimeSource::StartTicking() { void WallClockTimeSource::StartTicking() {
base::AutoLock auto_lock(lock_);
DCHECK(!ticking_); DCHECK(!ticking_);
ticking_ = true; ticking_ = true;
reference_wall_ticks_ = tick_clock_->NowTicks(); reference_wall_ticks_ = tick_clock_->NowTicks();
} }
void WallClockTimeSource::StopTicking() { void WallClockTimeSource::StopTicking() {
base::AutoLock auto_lock(lock_);
DCHECK(ticking_); DCHECK(ticking_);
base_time_ = CurrentMediaTime(); base_time_ = CurrentMediaTime_Locked();
ticking_ = false; ticking_ = false;
reference_wall_ticks_ = tick_clock_->NowTicks(); reference_wall_ticks_ = tick_clock_->NowTicks();
} }
void WallClockTimeSource::SetPlaybackRate(float playback_rate) { 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 // Estimate current media time using old rate to use as a new base time for
// the new rate. // the new rate.
if (ticking_) { if (ticking_) {
base_time_ = CurrentMediaTime(); base_time_ = CurrentMediaTime_Locked();
reference_wall_ticks_ = tick_clock_->NowTicks(); reference_wall_ticks_ = tick_clock_->NowTicks();
} }
...@@ -43,18 +46,14 @@ void WallClockTimeSource::SetPlaybackRate(float playback_rate) { ...@@ -43,18 +46,14 @@ void WallClockTimeSource::SetPlaybackRate(float playback_rate) {
} }
void WallClockTimeSource::SetMediaTime(base::TimeDelta time) { void WallClockTimeSource::SetMediaTime(base::TimeDelta time) {
base::AutoLock auto_lock(lock_);
CHECK(!ticking_); CHECK(!ticking_);
base_time_ = time; base_time_ = time;
} }
base::TimeDelta WallClockTimeSource::CurrentMediaTime() { base::TimeDelta WallClockTimeSource::CurrentMediaTime() {
if (!ticking_) base::AutoLock auto_lock(lock_);
return base_time_; return CurrentMediaTime_Locked();
base::TimeTicks now = tick_clock_->NowTicks();
return base_time_ +
base::TimeDelta::FromMicroseconds(
(now - reference_wall_ticks_).InMicroseconds() * playback_rate_);
} }
base::TimeDelta WallClockTimeSource::CurrentMediaTimeForSyncingVideo() { base::TimeDelta WallClockTimeSource::CurrentMediaTimeForSyncingVideo() {
...@@ -66,4 +65,15 @@ void WallClockTimeSource::SetTickClockForTesting( ...@@ -66,4 +65,15 @@ void WallClockTimeSource::SetTickClockForTesting(
tick_clock_.swap(tick_clock); 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 } // namespace media
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define MEDIA_BASE_WALL_CLOCK_TIME_SOURCE_H_ #define MEDIA_BASE_WALL_CLOCK_TIME_SOURCE_H_
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "media/base/time_source.h" #include "media/base/time_source.h"
...@@ -32,6 +33,8 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource { ...@@ -32,6 +33,8 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource {
void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock); void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock);
private: private:
base::TimeDelta CurrentMediaTime_Locked();
scoped_ptr<base::TickClock> tick_clock_; scoped_ptr<base::TickClock> tick_clock_;
bool ticking_; bool ticking_;
...@@ -42,6 +45,10 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource { ...@@ -42,6 +45,10 @@ class MEDIA_EXPORT WallClockTimeSource : public TimeSource {
base::TimeDelta base_time_; base::TimeDelta base_time_;
base::TimeTicks reference_wall_ticks_; 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); 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