Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/renderers/audio_renderer_impl.h" | 5 #include "media/renderers/audio_renderer_impl.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 static double kOutputMicrosPerFrame = | 59 static double kOutputMicrosPerFrame = |
| 60 static_cast<double>(base::Time::kMicrosecondsPerSecond) / | 60 static_cast<double>(base::Time::kMicrosecondsPerSecond) / |
| 61 kOutputSamplesPerSecond; | 61 kOutputSamplesPerSecond; |
| 62 | 62 |
| 63 ACTION_P(EnterPendingDecoderInitStateAction, test) { | 63 ACTION_P(EnterPendingDecoderInitStateAction, test) { |
| 64 test->EnterPendingDecoderInitState(arg2); | 64 test->EnterPendingDecoderInitState(arg2); |
| 65 } | 65 } |
| 66 | 66 |
| 67 class AudioRendererImplTest : public ::testing::Test, public RendererClient { | 67 class AudioRendererImplTest : public ::testing::Test, public RendererClient { |
| 68 public: | 68 public: |
| 69 ScopedVector<AudioDecoder> CreateAudioDecoderForTest() { | |
| 70 MockAudioDecoder* decoder = new MockAudioDecoder(); | |
| 71 if (!enter_pending_decoder_init_) { | |
| 72 EXPECT_CALL(*decoder, Initialize(_, _, _, _)) | |
| 73 .WillOnce(DoAll(SaveArg<3>(&output_cb_), | |
| 74 RunCallback<2>(expected_init_result_))); | |
| 75 } else { | |
| 76 EXPECT_CALL(*decoder, Initialize(_, _, _, _)) | |
| 77 .WillOnce(EnterPendingDecoderInitStateAction(this)); | |
| 78 } | |
| 79 EXPECT_CALL(*decoder, Decode(_, _)) | |
| 80 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder)); | |
| 81 EXPECT_CALL(*decoder, Reset(_)) | |
| 82 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder)); | |
| 83 ScopedVector<AudioDecoder> decoders; | |
| 84 decoders.push_back(decoder); | |
| 85 return decoders; | |
| 86 } | |
| 87 | |
| 69 // Give the decoder some non-garbage media properties. | 88 // Give the decoder some non-garbage media properties. |
| 70 AudioRendererImplTest() | 89 AudioRendererImplTest() |
| 71 : hardware_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 90 : hardware_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 72 kChannelLayout, | 91 kChannelLayout, |
| 73 kOutputSamplesPerSecond, | 92 kOutputSamplesPerSecond, |
| 74 SampleFormatToBytesPerChannel(kSampleFormat) * 8, | 93 SampleFormatToBytesPerChannel(kSampleFormat) * 8, |
| 75 512), | 94 512), |
| 76 sink_(new FakeAudioRendererSink(hardware_params_)), | 95 sink_(new FakeAudioRendererSink(hardware_params_)), |
| 77 tick_clock_(new base::SimpleTestTickClock()), | 96 tick_clock_(new base::SimpleTestTickClock()), |
| 78 demuxer_stream_(DemuxerStream::AUDIO), | 97 demuxer_stream_(DemuxerStream::AUDIO), |
| 79 decoder_(new MockAudioDecoder()), | 98 expected_init_result_(true), |
| 99 enter_pending_decoder_init_(false), | |
| 80 ended_(false) { | 100 ended_(false) { |
| 81 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, | 101 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, |
| 82 kInputSamplesPerSecond, EmptyExtraData(), | 102 kInputSamplesPerSecond, EmptyExtraData(), |
| 83 Unencrypted()); | 103 Unencrypted()); |
| 84 demuxer_stream_.set_audio_decoder_config(audio_config); | 104 demuxer_stream_.set_audio_decoder_config(audio_config); |
| 85 | 105 |
| 86 ConfigureDecoder(); | |
| 87 ConfigureDemuxerStream(true); | 106 ConfigureDemuxerStream(true); |
| 88 | 107 |
| 89 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 108 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 90 kChannelLayout, | 109 kChannelLayout, |
| 91 kOutputSamplesPerSecond, | 110 kOutputSamplesPerSecond, |
| 92 SampleFormatToBytesPerChannel(kSampleFormat) * 8, | 111 SampleFormatToBytesPerChannel(kSampleFormat) * 8, |
| 93 512); | 112 512); |
| 94 ScopedVector<AudioDecoder> decoders; | 113 renderer_.reset(new AudioRendererImpl( |
| 95 decoders.push_back(decoder_); | 114 message_loop_.task_runner(), sink_.get(), |
| 96 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), | 115 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest, |
| 97 sink_.get(), std::move(decoders), | 116 base::Unretained(this)), |
| 98 new MediaLog())); | 117 new MediaLog())); |
| 99 renderer_->tick_clock_.reset(tick_clock_); | 118 renderer_->tick_clock_.reset(tick_clock_); |
| 100 tick_clock_->Advance(base::TimeDelta::FromSeconds(1)); | 119 tick_clock_->Advance(base::TimeDelta::FromSeconds(1)); |
| 101 } | 120 } |
| 102 | 121 |
| 103 virtual ~AudioRendererImplTest() { | 122 virtual ~AudioRendererImplTest() { |
| 104 SCOPED_TRACE("~AudioRendererImplTest()"); | 123 SCOPED_TRACE("~AudioRendererImplTest()"); |
| 105 } | 124 } |
| 106 | 125 |
| 107 // Used to save callbacks and run them at a later time. | |
| 108 void ConfigureDecoder() { | |
| 109 EXPECT_CALL(*decoder_, Decode(_, _)) | |
| 110 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder)); | |
| 111 EXPECT_CALL(*decoder_, Reset(_)) | |
| 112 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder)); | |
| 113 } | |
| 114 | |
| 115 // Mock out demuxer reads. | 126 // Mock out demuxer reads. |
| 116 void ConfigureDemuxerStream(bool supports_config_changes) { | 127 void ConfigureDemuxerStream(bool supports_config_changes) { |
| 117 EXPECT_CALL(demuxer_stream_, Read(_)) | 128 EXPECT_CALL(demuxer_stream_, Read(_)) |
| 118 .WillRepeatedly( | 129 .WillRepeatedly( |
| 119 RunCallback<0>(DemuxerStream::kOk, | 130 RunCallback<0>(DemuxerStream::kOk, |
| 120 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); | 131 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); |
| 121 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges()) | 132 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges()) |
| 122 .WillRepeatedly(Return(supports_config_changes)); | 133 .WillRepeatedly(Return(supports_config_changes)); |
| 123 } | 134 } |
| 124 | 135 |
| 125 // Reconfigures a renderer without config change support using given params. | 136 // Reconfigures a renderer without config change support using given params. |
| 126 void ConfigureBasicRenderer(const AudioParameters& params) { | 137 void ConfigureBasicRenderer(const AudioParameters& params) { |
| 127 hardware_params_ = params; | 138 hardware_params_ = params; |
| 128 sink_ = new FakeAudioRendererSink(hardware_params_); | 139 sink_ = new FakeAudioRendererSink(hardware_params_); |
| 129 decoder_ = new MockAudioDecoder(); | 140 renderer_.reset(new AudioRendererImpl( |
| 130 ConfigureDecoder(); | 141 message_loop_.task_runner(), sink_.get(), |
| 131 ScopedVector<AudioDecoder> decoders; | 142 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest, |
| 132 decoders.push_back(decoder_); | 143 base::Unretained(this)), |
| 133 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), | 144 new MediaLog())); |
| 134 sink_.get(), std::move(decoders), | |
| 135 new MediaLog())); | |
| 136 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); | 145 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); |
| 137 ConfigureDemuxerStream(false); | 146 ConfigureDemuxerStream(false); |
| 138 } | 147 } |
| 139 | 148 |
| 140 // Reconfigures a renderer with config change support using given params. | 149 // Reconfigures a renderer with config change support using given params. |
| 141 void ConfigureConfigChangeRenderer(const AudioParameters& params, | 150 void ConfigureConfigChangeRenderer(const AudioParameters& params, |
| 142 const AudioParameters& hardware_params) { | 151 const AudioParameters& hardware_params) { |
| 143 hardware_params_ = hardware_params; | 152 hardware_params_ = hardware_params; |
| 144 sink_ = new FakeAudioRendererSink(hardware_params_); | 153 sink_ = new FakeAudioRendererSink(hardware_params_); |
| 145 decoder_ = new MockAudioDecoder(); | 154 renderer_.reset(new AudioRendererImpl( |
| 146 ConfigureDecoder(); | 155 message_loop_.task_runner(), sink_.get(), |
| 147 ScopedVector<AudioDecoder> decoders; | 156 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest, |
| 148 decoders.push_back(decoder_); | 157 base::Unretained(this)), |
| 149 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), | 158 new MediaLog())); |
| 150 sink_.get(), std::move(decoders), | |
| 151 new MediaLog())); | |
| 152 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); | 159 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); |
| 153 ConfigureDemuxerStream(true); | 160 ConfigureDemuxerStream(true); |
| 154 } | 161 } |
| 155 | 162 |
| 156 void ExpectUnsupportedAudioDecoder() { | |
| 157 EXPECT_CALL(*decoder_, Initialize(_, _, _, _)) | |
| 158 .WillOnce(DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(false))); | |
| 159 } | |
| 160 | |
| 161 // RendererClient implementation. | 163 // RendererClient implementation. |
| 162 MOCK_METHOD1(OnError, void(PipelineStatus)); | 164 MOCK_METHOD1(OnError, void(PipelineStatus)); |
| 163 void OnEnded() override { | 165 void OnEnded() override { |
| 164 CHECK(!ended_); | 166 CHECK(!ended_); |
| 165 ended_ = true; | 167 ended_ = true; |
| 166 } | 168 } |
| 167 void OnStatisticsUpdate(const PipelineStatistics& stats) override { | 169 void OnStatisticsUpdate(const PipelineStatistics& stats) override { |
| 168 last_statistics_.audio_memory_usage += stats.audio_memory_usage; | 170 last_statistics_.audio_memory_usage += stats.audio_memory_usage; |
| 169 } | 171 } |
| 170 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); | 172 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
| 171 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); | 173 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); |
| 172 MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); | 174 MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); |
| 173 MOCK_METHOD1(OnVideoOpacityChange, void(bool)); | 175 MOCK_METHOD1(OnVideoOpacityChange, void(bool)); |
| 174 MOCK_METHOD1(OnDurationChange, void(base::TimeDelta)); | 176 MOCK_METHOD1(OnDurationChange, void(base::TimeDelta)); |
| 175 | 177 |
| 176 void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { | 178 void InitializeRenderer(DemuxerStream* demuxer_stream, |
| 179 const PipelineStatusCB& pipeline_status_cb) { | |
| 177 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); | 180 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); |
| 178 EXPECT_CALL(*this, OnVideoNaturalSizeChange(_)).Times(0); | 181 EXPECT_CALL(*this, OnVideoNaturalSizeChange(_)).Times(0); |
| 179 EXPECT_CALL(*this, OnVideoOpacityChange(_)).Times(0); | 182 EXPECT_CALL(*this, OnVideoOpacityChange(_)).Times(0); |
| 180 renderer_->Initialize(&demuxer_stream_, nullptr, this, pipeline_status_cb); | 183 renderer_->Initialize(demuxer_stream, nullptr, this, pipeline_status_cb); |
| 181 } | 184 } |
| 182 | 185 |
| 183 void Initialize() { | 186 void Initialize() { |
| 184 EXPECT_CALL(*decoder_, Initialize(_, _, _, _)) | |
| 185 .WillOnce(DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(true))); | |
| 186 InitializeWithStatus(PIPELINE_OK); | 187 InitializeWithStatus(PIPELINE_OK); |
| 187 | 188 |
| 188 next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond)); | 189 next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond)); |
| 189 } | 190 } |
| 190 | 191 |
| 191 void InitializeWithStatus(PipelineStatus expected) { | 192 void InitializeWithStatus(PipelineStatus expected) { |
| 192 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); | 193 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); |
| 193 | 194 |
| 194 WaitableMessageLoopEvent event; | 195 WaitableMessageLoopEvent event; |
| 195 InitializeRenderer(event.GetPipelineStatusCB()); | 196 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB()); |
| 196 event.RunAndWaitForStatus(expected); | 197 event.RunAndWaitForStatus(expected); |
| 197 | 198 |
| 198 // We should have no reads. | 199 // We should have no reads. |
| 199 EXPECT_TRUE(decode_cb_.is_null()); | 200 EXPECT_TRUE(decode_cb_.is_null()); |
| 200 } | 201 } |
| 201 | 202 |
| 202 void InitializeAndDestroy() { | 203 void InitializeAndDestroy() { |
| 203 EXPECT_CALL(*decoder_, Initialize(_, _, _, _)) | |
| 204 .WillOnce(RunCallback<2>(true)); | |
| 205 | |
| 206 WaitableMessageLoopEvent event; | 204 WaitableMessageLoopEvent event; |
| 207 InitializeRenderer(event.GetPipelineStatusCB()); | 205 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB()); |
| 208 | 206 |
| 209 // Destroy the |renderer_| before we let the MessageLoop run, this simulates | 207 // Destroy the |renderer_| before we let the MessageLoop run, this simulates |
| 210 // an interleaving in which we end up destroying the |renderer_| while the | 208 // an interleaving in which we end up destroying the |renderer_| while the |
| 211 // OnDecoderSelected callback is in flight. | 209 // OnDecoderSelected callback is in flight. |
| 212 renderer_.reset(); | 210 renderer_.reset(); |
| 213 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); | 211 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); |
| 214 } | 212 } |
| 215 | 213 |
| 216 void InitializeAndDestroyDuringDecoderInit() { | 214 void InitializeAndDestroyDuringDecoderInit() { |
| 217 EXPECT_CALL(*decoder_, Initialize(_, _, _, _)) | 215 enter_pending_decoder_init_ = true; |
| 218 .WillOnce(EnterPendingDecoderInitStateAction(this)); | |
| 219 | 216 |
| 220 WaitableMessageLoopEvent event; | 217 WaitableMessageLoopEvent event; |
| 221 InitializeRenderer(event.GetPipelineStatusCB()); | 218 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB()); |
| 222 base::RunLoop().RunUntilIdle(); | 219 base::RunLoop().RunUntilIdle(); |
| 223 DCHECK(!init_decoder_cb_.is_null()); | 220 DCHECK(!init_decoder_cb_.is_null()); |
| 224 | 221 |
| 225 renderer_.reset(); | 222 renderer_.reset(); |
| 226 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); | 223 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); |
| 227 } | 224 } |
| 228 | 225 |
| 229 void EnterPendingDecoderInitState(const AudioDecoder::InitCB& cb) { | 226 void EnterPendingDecoderInitState(const AudioDecoder::InitCB& cb) { |
| 230 init_decoder_cb_ = cb; | 227 init_decoder_cb_ = cb; |
| 231 } | 228 } |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 | 447 |
| 451 // Fixture members. | 448 // Fixture members. |
| 452 AudioParameters hardware_params_; | 449 AudioParameters hardware_params_; |
| 453 base::MessageLoop message_loop_; | 450 base::MessageLoop message_loop_; |
| 454 std::unique_ptr<AudioRendererImpl> renderer_; | 451 std::unique_ptr<AudioRendererImpl> renderer_; |
| 455 scoped_refptr<FakeAudioRendererSink> sink_; | 452 scoped_refptr<FakeAudioRendererSink> sink_; |
| 456 base::SimpleTestTickClock* tick_clock_; | 453 base::SimpleTestTickClock* tick_clock_; |
| 457 PipelineStatistics last_statistics_; | 454 PipelineStatistics last_statistics_; |
| 458 | 455 |
| 459 MockDemuxerStream demuxer_stream_; | 456 MockDemuxerStream demuxer_stream_; |
| 460 MockAudioDecoder* decoder_; | |
| 461 | 457 |
| 462 // Used for satisfying reads. | 458 // Used for satisfying reads. |
| 463 AudioDecoder::OutputCB output_cb_; | 459 AudioDecoder::OutputCB output_cb_; |
| 464 AudioDecoder::DecodeCB decode_cb_; | 460 AudioDecoder::DecodeCB decode_cb_; |
| 465 base::Closure reset_cb_; | 461 base::Closure reset_cb_; |
| 466 std::unique_ptr<AudioTimestampHelper> next_timestamp_; | 462 std::unique_ptr<AudioTimestampHelper> next_timestamp_; |
| 467 | 463 |
| 468 // Run during DecodeDecoder() to unblock WaitForPendingRead(). | 464 // Run during DecodeDecoder() to unblock WaitForPendingRead(). |
| 469 base::Closure wait_for_pending_decode_cb_; | 465 base::Closure wait_for_pending_decode_cb_; |
| 470 | 466 |
| 471 AudioDecoder::InitCB init_decoder_cb_; | 467 AudioDecoder::InitCB init_decoder_cb_; |
| 468 bool expected_init_result_; | |
| 469 bool enter_pending_decoder_init_; | |
| 472 bool ended_; | 470 bool ended_; |
| 473 | 471 |
| 474 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); | 472 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); |
| 475 }; | 473 }; |
| 476 | 474 |
| 477 TEST_F(AudioRendererImplTest, Initialize_Successful) { | 475 TEST_F(AudioRendererImplTest, Initialize_Successful) { |
| 478 Initialize(); | 476 Initialize(); |
| 479 } | 477 } |
| 480 | 478 |
| 481 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) { | 479 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) { |
| 482 ExpectUnsupportedAudioDecoder(); | 480 expected_init_result_ = false; |
| 483 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED); | 481 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED); |
| 484 } | 482 } |
| 485 | 483 |
|
DaleCurtis
2017/03/31 21:22:08
There needs to be a test for the track switch happ
servolk
2017/03/31 23:53:55
Done (in media/renderers/renderer_impl_unittest.cc
| |
| 484 TEST_F(AudioRendererImplTest, ReinitializeForDifferentStream) { | |
| 485 // Initialize and start playback | |
| 486 Initialize(); | |
| 487 Preroll(); | |
| 488 StartTicking(); | |
| 489 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256))); | |
| 490 WaitForPendingRead(); | |
| 491 | |
| 492 // Stop playback and flush | |
| 493 StopTicking(); | |
| 494 EXPECT_TRUE(IsReadPending()); | |
| 495 // Flush and expect to be notified that we have nothing. | |
| 496 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | |
| 497 FlushDuringPendingRead(); | |
| 498 | |
| 499 // Prepare a new demuxer stream. | |
| 500 MockDemuxerStream new_stream(DemuxerStream::AUDIO); | |
| 501 EXPECT_CALL(new_stream, SupportsConfigChanges()).WillOnce(Return(false)); | |
| 502 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, | |
| 503 kInputSamplesPerSecond, EmptyExtraData(), | |
| 504 Unencrypted()); | |
| 505 new_stream.set_audio_decoder_config(audio_config); | |
| 506 | |
| 507 // The renderer is now in the flushed state and can be reinitialized. | |
| 508 WaitableMessageLoopEvent event; | |
| 509 InitializeRenderer(&new_stream, event.GetPipelineStatusCB()); | |
| 510 event.RunAndWaitForStatus(PIPELINE_OK); | |
| 511 } | |
| 512 | |
| 486 TEST_F(AudioRendererImplTest, Preroll) { | 513 TEST_F(AudioRendererImplTest, Preroll) { |
| 487 Initialize(); | 514 Initialize(); |
| 488 Preroll(); | 515 Preroll(); |
| 489 } | 516 } |
| 490 | 517 |
| 491 TEST_F(AudioRendererImplTest, StartTicking) { | 518 TEST_F(AudioRendererImplTest, StartTicking) { |
| 492 Initialize(); | 519 Initialize(); |
| 493 Preroll(); | 520 Preroll(); |
| 494 StartTicking(); | 521 StartTicking(); |
| 495 | 522 |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1063 // Advance far enough that we shouldn't be clamped to current time (tested | 1090 // Advance far enough that we shouldn't be clamped to current time (tested |
| 1064 // already above). | 1091 // already above). |
| 1065 tick_clock_->Advance(kOneSecond); | 1092 tick_clock_->Advance(kOneSecond); |
| 1066 EXPECT_EQ( | 1093 EXPECT_EQ( |
| 1067 current_time + timestamp_helper.GetFrameDuration(frames_to_consume.value), | 1094 current_time + timestamp_helper.GetFrameDuration(frames_to_consume.value), |
| 1068 CurrentMediaWallClockTime(&is_time_moving)); | 1095 CurrentMediaWallClockTime(&is_time_moving)); |
| 1069 EXPECT_TRUE(is_time_moving); | 1096 EXPECT_TRUE(is_time_moving); |
| 1070 } | 1097 } |
| 1071 | 1098 |
| 1072 } // namespace media | 1099 } // namespace media |
| OLD | NEW |