Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: media/renderers/video_renderer_impl_unittest.cc

Issue 1027553002: Change the TimeSource interface to return wallclock time for video. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix comment. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 <utility> 5 #include <utility>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/debug/stack_trace.h" 10 #include "base/debug/stack_trace.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
17 #include "base/test/simple_test_tick_clock.h"
17 #include "media/base/data_buffer.h" 18 #include "media/base/data_buffer.h"
18 #include "media/base/gmock_callback_support.h" 19 #include "media/base/gmock_callback_support.h"
19 #include "media/base/limits.h" 20 #include "media/base/limits.h"
20 #include "media/base/mock_filters.h" 21 #include "media/base/mock_filters.h"
21 #include "media/base/test_helpers.h" 22 #include "media/base/test_helpers.h"
22 #include "media/base/video_frame.h" 23 #include "media/base/video_frame.h"
23 #include "media/renderers/video_renderer_impl.h" 24 #include "media/renderers/video_renderer_impl.h"
24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
25 26
26 using ::testing::_; 27 using ::testing::_;
(...skipping 11 matching lines...) Expand all
38 } 39 }
39 40
40 MATCHER_P(HasTimestamp, ms, "") { 41 MATCHER_P(HasTimestamp, ms, "") {
41 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); 42 *result_listener << "has timestamp " << arg->timestamp().InMilliseconds();
42 return arg->timestamp().InMilliseconds() == ms; 43 return arg->timestamp().InMilliseconds() == ms;
43 } 44 }
44 45
45 class VideoRendererImplTest : public ::testing::Test { 46 class VideoRendererImplTest : public ::testing::Test {
46 public: 47 public:
47 VideoRendererImplTest() 48 VideoRendererImplTest()
48 : decoder_(new MockVideoDecoder()), 49 : tick_clock_(new base::SimpleTestTickClock()),
50 decoder_(new MockVideoDecoder()),
49 demuxer_stream_(DemuxerStream::VIDEO) { 51 demuxer_stream_(DemuxerStream::VIDEO) {
50 ScopedVector<VideoDecoder> decoders; 52 ScopedVector<VideoDecoder> decoders;
51 decoders.push_back(decoder_); 53 decoders.push_back(decoder_);
52 54
53 renderer_.reset(new VideoRendererImpl(message_loop_.message_loop_proxy(), 55 renderer_.reset(new VideoRendererImpl(message_loop_.message_loop_proxy(),
54 decoders.Pass(), true, 56 decoders.Pass(), true,
55 new MediaLog())); 57 new MediaLog()));
58 renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_));
59
60 // Start wallclock time at a non-zero value.
61 AdvanceWallclockTimeInMs(12345);
56 62
57 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); 63 demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal());
58 64
59 // We expect these to be called but we don't care how/when. 65 // We expect these to be called but we don't care how/when.
60 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly( 66 EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly(
61 RunCallback<0>(DemuxerStream::kOk, 67 RunCallback<0>(DemuxerStream::kOk,
62 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); 68 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0))));
63 } 69 }
64 70
65 virtual ~VideoRendererImplTest() {} 71 virtual ~VideoRendererImplTest() {}
(...skipping 30 matching lines...) Expand all
96 DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(decoder_status))); 102 DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(decoder_status)));
97 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); 103 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
98 renderer_->Initialize( 104 renderer_->Initialize(
99 &demuxer_stream_, status_cb, media::SetDecryptorReadyCB(), 105 &demuxer_stream_, status_cb, media::SetDecryptorReadyCB(),
100 base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, 106 base::Bind(&VideoRendererImplTest::OnStatisticsUpdate,
101 base::Unretained(this)), 107 base::Unretained(this)),
102 base::Bind(&StrictMock<MockCB>::BufferingStateChange, 108 base::Bind(&StrictMock<MockCB>::BufferingStateChange,
103 base::Unretained(&mock_cb_)), 109 base::Unretained(&mock_cb_)),
104 base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)), 110 base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)),
105 ended_event_.GetClosure(), error_event_.GetPipelineStatusCB(), 111 ended_event_.GetClosure(), error_event_.GetPipelineStatusCB(),
106 base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), 112 base::Bind(&VideoRendererImplTest::GetWallclockTimeForMediaTime,
113 base::Unretained(this)),
107 base::Bind(&VideoRendererImplTest::OnWaitingForDecryptionKey, 114 base::Bind(&VideoRendererImplTest::OnWaitingForDecryptionKey,
108 base::Unretained(this))); 115 base::Unretained(this)));
109 } 116 }
110 117
111 void StartPlayingFrom(int milliseconds) { 118 void StartPlayingFrom(int milliseconds) {
112 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); 119 SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds));
113 renderer_->StartPlayingFrom( 120 renderer_->StartPlayingFrom(
114 base::TimeDelta::FromMilliseconds(milliseconds)); 121 base::TimeDelta::FromMilliseconds(milliseconds));
115 message_loop_.RunUntilIdle(); 122 message_loop_.RunUntilIdle();
116 } 123 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 FROM_HERE, 237 FROM_HERE,
231 base::Bind(base::ResetAndReturn(&decode_cb_), VideoDecoder::kOk)); 238 base::Bind(base::ResetAndReturn(&decode_cb_), VideoDecoder::kOk));
232 239
233 WaitForPendingRead(); 240 WaitForPendingRead();
234 241
235 message_loop_.PostTask( 242 message_loop_.PostTask(
236 FROM_HERE, 243 FROM_HERE,
237 base::Bind(base::ResetAndReturn(&decode_cb_), VideoDecoder::kOk)); 244 base::Bind(base::ResetAndReturn(&decode_cb_), VideoDecoder::kOk));
238 } 245 }
239 246
247 void AdvanceWallclockTimeInMs(int time_ms) {
248 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
249 base::AutoLock l(lock_);
250 tick_clock_->Advance(base::TimeDelta::FromMilliseconds(time_ms));
251 }
252
240 void AdvanceTimeInMs(int time_ms) { 253 void AdvanceTimeInMs(int time_ms) {
241 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 254 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
242 base::AutoLock l(lock_); 255 base::AutoLock l(lock_);
243 time_ += base::TimeDelta::FromMilliseconds(time_ms); 256 time_ += base::TimeDelta::FromMilliseconds(time_ms);
244 } 257 }
245 258
246 protected: 259 protected:
247 // Fixture members. 260 // Fixture members.
248 scoped_ptr<VideoRendererImpl> renderer_; 261 scoped_ptr<VideoRendererImpl> renderer_;
262 base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|.
249 MockVideoDecoder* decoder_; // Owned by |renderer_|. 263 MockVideoDecoder* decoder_; // Owned by |renderer_|.
250 NiceMock<MockDemuxerStream> demuxer_stream_; 264 NiceMock<MockDemuxerStream> demuxer_stream_;
251 265
252 // Use StrictMock<T> to catch missing/extra callbacks. 266 // Use StrictMock<T> to catch missing/extra callbacks.
253 class MockCB { 267 class MockCB {
254 public: 268 public:
255 MOCK_METHOD1(Display, void(const scoped_refptr<VideoFrame>&)); 269 MOCK_METHOD1(Display, void(const scoped_refptr<VideoFrame>&));
256 MOCK_METHOD1(BufferingStateChange, void(BufferingState)); 270 MOCK_METHOD1(BufferingStateChange, void(BufferingState));
257 }; 271 };
258 StrictMock<MockCB> mock_cb_; 272 StrictMock<MockCB> mock_cb_;
259 273
260 private: 274 private:
261 base::TimeDelta GetTime() { 275 base::TimeTicks GetWallclockTimeForMediaTime(base::TimeDelta time) {
262 base::AutoLock l(lock_); 276 base::AutoLock l(lock_);
263 return time_; 277 return tick_clock_->NowTicks() + (time - time_);
264 } 278 }
265 279
266 void DecodeRequested(const scoped_refptr<DecoderBuffer>& buffer, 280 void DecodeRequested(const scoped_refptr<DecoderBuffer>& buffer,
267 const VideoDecoder::DecodeCB& decode_cb) { 281 const VideoDecoder::DecodeCB& decode_cb) {
268 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 282 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
269 CHECK(decode_cb_.is_null()); 283 CHECK(decode_cb_.is_null());
270 decode_cb_ = decode_cb; 284 decode_cb_ = decode_cb;
271 285
272 // Wake up WaitForPendingRead() if needed. 286 // Wake up WaitForPendingRead() if needed.
273 if (!wait_for_pending_decode_cb_.is_null()) 287 if (!wait_for_pending_decode_cb_.is_null())
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 Initialize(); 487 Initialize();
474 QueueFrames("0 10 20 30"); 488 QueueFrames("0 10 20 30");
475 EXPECT_CALL(mock_cb_, Display(HasTimestamp(0))); 489 EXPECT_CALL(mock_cb_, Display(HasTimestamp(0)));
476 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)); 490 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH));
477 StartPlayingFrom(0); 491 StartPlayingFrom(0);
478 492
479 // Advance time slightly. Frames should be dropped and we should NOT signal 493 // Advance time slightly. Frames should be dropped and we should NOT signal
480 // having nothing. 494 // having nothing.
481 AdvanceTimeInMs(100); 495 AdvanceTimeInMs(100);
482 496
483 // Advance time more. Now we should signal having nothing. 497 // Now that all frames are dropped, we should signal having nothing.
484 { 498 {
485 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING"); 499 SCOPED_TRACE("Waiting for BUFFERING_HAVE_NOTHING");
486 WaitableMessageLoopEvent event; 500 WaitableMessageLoopEvent event;
487 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING)) 501 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_NOTHING))
488 .WillOnce(RunClosure(event.GetClosure())); 502 .WillOnce(RunClosure(event.GetClosure()));
489 AdvanceTimeInMs(3000); // Must match kTimeToDeclareHaveNothing.
490 event.RunAndWait(); 503 event.RunAndWait();
491 } 504 }
492 505
493 // Receiving end of stream should signal having enough. 506 // Receiving end of stream should signal having enough.
494 { 507 {
495 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH"); 508 SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH");
496 WaitableMessageLoopEvent event; 509 WaitableMessageLoopEvent event;
497 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH)) 510 EXPECT_CALL(mock_cb_, BufferingStateChange(BUFFERING_HAVE_ENOUGH))
498 .WillOnce(RunClosure(event.GetClosure())); 511 .WillOnce(RunClosure(event.GetClosure()));
499 SatisfyPendingReadWithEndOfStream(); 512 SatisfyPendingReadWithEndOfStream();
500 event.RunAndWait(); 513 event.RunAndWait();
501 } 514 }
502 515
503 WaitForEnded(); 516 WaitForEnded();
504 Destroy(); 517 Destroy();
505 } 518 }
506 519
507 } // namespace media 520 } // namespace media
OLDNEW
« media/renderers/video_renderer_impl.cc ('K') | « media/renderers/video_renderer_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698