summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-06 06:58:38 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-06 06:58:38 +0000
commit1848da07b207f323d31883e565cdf1229137a075 (patch)
tree5240eecce5de5266f3a70e49fbedaaa49fd130fc /media
parent300ba0c4a5d7fc82c0ab0952ff3d5596f727f611 (diff)
downloadchromium_src-1848da07b207f323d31883e565cdf1229137a075.zip
chromium_src-1848da07b207f323d31883e565cdf1229137a075.tar.gz
chromium_src-1848da07b207f323d31883e565cdf1229137a075.tar.bz2
Replace WaitableEvents and ConditionalVariables in VideoRendererBase tests with MessageLoop.
Review URL: https://chromiumcodereview.appspot.com/11316293 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171438 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/mock_callback.cc43
-rw-r--r--media/base/mock_callback.h36
-rw-r--r--media/base/pipeline_unittest.cc2
-rw-r--r--media/base/test_helpers.cc99
-rw-r--r--media/base/test_helpers.h57
-rw-r--r--media/filters/audio_renderer_impl_unittest.cc2
-rw-r--r--media/filters/chunk_demuxer_unittest.cc2
-rw-r--r--media/filters/decrypting_audio_decoder_unittest.cc2
-rw-r--r--media/filters/decrypting_demuxer_stream_unittest.cc2
-rw-r--r--media/filters/decrypting_video_decoder_unittest.cc2
-rw-r--r--media/filters/ffmpeg_audio_decoder_unittest.cc2
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc44
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc2
-rw-r--r--media/filters/file_data_source_unittest.cc2
-rw-r--r--media/filters/video_renderer_base_unittest.cc566
-rw-r--r--media/media.gyp4
16 files changed, 432 insertions, 435 deletions
diff --git a/media/base/mock_callback.cc b/media/base/mock_callback.cc
deleted file mode 100644
index e9d2da3..0000000
--- a/media/base/mock_callback.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2012 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/mock_callback.h"
-
-#include "base/bind.h"
-
-using ::testing::_;
-using ::testing::StrictMock;
-
-namespace media {
-
-MockClosure::MockClosure() {}
-MockClosure::~MockClosure() {}
-
-base::Closure NewExpectedClosure() {
- StrictMock<MockClosure>* callback = new StrictMock<MockClosure>();
- EXPECT_CALL(*callback, Run());
- return base::Bind(&MockClosure::Run, callback);
-}
-
-class MockStatusCB : public base::RefCountedThreadSafe<MockStatusCB> {
- public:
- MockStatusCB() {}
- MOCK_METHOD1(Run, void(PipelineStatus));
-
- protected:
- friend class base::RefCountedThreadSafe<MockStatusCB>;
- virtual ~MockStatusCB() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockStatusCB);
-};
-
-base::Callback<void(PipelineStatus)> NewExpectedStatusCB(
- PipelineStatus status) {
- StrictMock<MockStatusCB>* callback = new StrictMock<MockStatusCB>();
- EXPECT_CALL(*callback, Run(status));
- return base::Bind(&MockStatusCB::Run, callback);
-}
-
-} // namespace media
diff --git a/media/base/mock_callback.h b/media/base/mock_callback.h
deleted file mode 100644
index 00d8276..0000000
--- a/media/base/mock_callback.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef MEDIA_BASE_MOCK_CALLBACK_H_
-#define MEDIA_BASE_MOCK_CALLBACK_H_
-
-#include "base/callback.h"
-#include "media/base/pipeline_status.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace media {
-
-// Utility mock for testing methods expecting Closures. See
-// NewExpectedClosure() below for a helper suitable when expectation order is
-// not checked (or when the expectation can be set at mock construction time).
-class MockClosure : public base::RefCountedThreadSafe<MockClosure> {
- public:
- MockClosure();
- MOCK_METHOD0(Run, void());
-
- protected:
- friend class base::RefCountedThreadSafe<MockClosure>;
- virtual ~MockClosure();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockClosure);
-};
-
-// Return a callback that expects to be run once.
-base::Closure NewExpectedClosure();
-base::Callback<void(PipelineStatus)> NewExpectedStatusCB(PipelineStatus status);
-
-} // namespace media
-
-#endif // MEDIA_BASE_MOCK_CALLBACK_H_
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 085aa8a..a12f91c 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -11,9 +11,9 @@
#include "media/base/clock.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/media_log.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
#include "media/base/pipeline.h"
+#include "media/base/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/size.h"
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc
new file mode 100644
index 0000000..862c9d4
--- /dev/null
+++ b/media/base/test_helpers.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 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/test_helpers.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/test/test_timeouts.h"
+#include "base/timer.h"
+#include "media/base/bind_to_loop.h"
+
+using ::testing::_;
+using ::testing::StrictMock;
+
+namespace media {
+
+// Utility mock for testing methods expecting Closures and PipelineStatusCBs.
+class MockCallback : public base::RefCountedThreadSafe<MockCallback> {
+ public:
+ MockCallback();
+ MOCK_METHOD0(Run, void());
+ MOCK_METHOD1(RunWithStatus, void(PipelineStatus));
+
+ protected:
+ friend class base::RefCountedThreadSafe<MockCallback>;
+ virtual ~MockCallback();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockCallback);
+};
+
+MockCallback::MockCallback() {}
+MockCallback::~MockCallback() {}
+
+base::Closure NewExpectedClosure() {
+ StrictMock<MockCallback>* callback = new StrictMock<MockCallback>();
+ EXPECT_CALL(*callback, Run());
+ return base::Bind(&MockCallback::Run, callback);
+}
+
+PipelineStatusCB NewExpectedStatusCB(PipelineStatus status) {
+ StrictMock<MockCallback>* callback = new StrictMock<MockCallback>();
+ EXPECT_CALL(*callback, RunWithStatus(status));
+ return base::Bind(&MockCallback::RunWithStatus, callback);
+}
+
+WaitableMessageLoopEvent::WaitableMessageLoopEvent()
+ : message_loop_(MessageLoop::current()),
+ signaled_(false),
+ status_(PIPELINE_OK) {
+ DCHECK(message_loop_);
+}
+
+WaitableMessageLoopEvent::~WaitableMessageLoopEvent() {}
+
+base::Closure WaitableMessageLoopEvent::GetClosure() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ return BindToLoop(message_loop_->message_loop_proxy(), base::Bind(
+ &WaitableMessageLoopEvent::OnCallback, base::Unretained(this),
+ PIPELINE_OK));
+}
+
+PipelineStatusCB WaitableMessageLoopEvent::GetPipelineStatusCB() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ return BindToLoop(message_loop_->message_loop_proxy(), base::Bind(
+ &WaitableMessageLoopEvent::OnCallback, base::Unretained(this)));
+}
+
+void WaitableMessageLoopEvent::RunAndWait() {
+ RunAndWaitForStatus(PIPELINE_OK);
+}
+
+void WaitableMessageLoopEvent::RunAndWaitForStatus(PipelineStatus expected) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ base::Timer timer(false, false);
+ timer.Start(FROM_HERE, TestTimeouts::action_timeout(), base::Bind(
+ &WaitableMessageLoopEvent::OnTimeout, base::Unretained(this)));
+
+ DCHECK(!signaled_) << "Already signaled";
+ message_loop_->Run();
+ EXPECT_TRUE(signaled_);
+ EXPECT_EQ(expected, status_);
+}
+
+void WaitableMessageLoopEvent::OnCallback(PipelineStatus status) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ signaled_ = true;
+ status_ = status;
+ message_loop_->QuitWhenIdle();
+}
+
+void WaitableMessageLoopEvent::OnTimeout() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ ADD_FAILURE() << "Timed out waiting for message loop to quit";
+ message_loop_->QuitWhenIdle();
+}
+
+} // namespace media
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h
new file mode 100644
index 0000000..1c38694
--- /dev/null
+++ b/media/base/test_helpers.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 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.
+
+#ifndef MEDIA_BASE_TEST_HELPERS_H_
+#define MEDIA_BASE_TEST_HELPERS_H_
+
+#include "base/callback.h"
+#include "media/base/pipeline_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+class MessageLoop;
+
+namespace media {
+
+// Return a callback that expects to be run once.
+base::Closure NewExpectedClosure();
+PipelineStatusCB NewExpectedStatusCB(PipelineStatus status);
+
+// Helper class for running a message loop until a callback has run. Useful for
+// testing classes that run on more than a single thread.
+//
+// Events are intended for single use and cannot be reset.
+class WaitableMessageLoopEvent {
+ public:
+ WaitableMessageLoopEvent();
+ ~WaitableMessageLoopEvent();
+
+ // Returns a thread-safe closure that will signal |this| when executed.
+ base::Closure GetClosure();
+ PipelineStatusCB GetPipelineStatusCB();
+
+ // Runs the current message loop until |this| has been signaled.
+ //
+ // Fails the test if the timeout is reached.
+ void RunAndWait();
+
+ // Runs the current message loop until |this| has been signaled and asserts
+ // that the |expected| status was received.
+ //
+ // Fails the test if the timeout is reached.
+ void RunAndWaitForStatus(PipelineStatus expected);
+
+ private:
+ void OnCallback(PipelineStatus status);
+ void OnTimeout();
+
+ MessageLoop* message_loop_;
+ bool signaled_;
+ PipelineStatus status_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaitableMessageLoopEvent);
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_TEST_HELPERS_H_
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 4f741d9..23f2078 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -11,8 +11,8 @@
#include "media/base/data_buffer.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/mock_audio_renderer_sink.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
#include "media/filters/audio_renderer_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 8f4fa4e..3fbfa6b 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -6,9 +6,9 @@
#include "base/message_loop.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decoder_buffer.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_demuxer_host.h"
#include "media/base/test_data_util.h"
+#include "media/base/test_helpers.h"
#include "media/filters/chunk_demuxer.h"
#include "media/webm/cluster_builder.h"
#include "media/webm/webm_constants.h"
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc
index b4c2a7b..a6a897f 100644
--- a/media/filters/decrypting_audio_decoder_unittest.cc
+++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -13,8 +13,8 @@
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/gmock_callback_support.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
#include "media/filters/decrypting_audio_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc
index f952d82..3e85d7f 100644
--- a/media/filters/decrypting_demuxer_stream_unittest.cc
+++ b/media/filters/decrypting_demuxer_stream_unittest.cc
@@ -11,8 +11,8 @@
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/gmock_callback_support.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
#include "media/filters/decrypting_demuxer_stream.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc
index efaf4d8..3007637 100644
--- a/media/filters/decrypting_video_decoder_unittest.cc
+++ b/media/filters/decrypting_video_decoder_unittest.cc
@@ -11,8 +11,8 @@
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/gmock_callback_support.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
#include "media/base/video_frame.h"
#include "media/filters/decrypting_video_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/media/filters/ffmpeg_audio_decoder_unittest.cc b/media/filters/ffmpeg_audio_decoder_unittest.cc
index 2ad7ab8..ead293d 100644
--- a/media/filters/ffmpeg_audio_decoder_unittest.cc
+++ b/media/filters/ffmpeg_audio_decoder_unittest.cc
@@ -8,9 +8,9 @@
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "media/base/decoder_buffer.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
#include "media/base/test_data_util.h"
+#include "media/base/test_helpers.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_audio_decoder.h"
#include "media/filters/ffmpeg_glue.h"
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 9ce8659..e0dc371 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -11,8 +11,8 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/threading/thread.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_demuxer_host.h"
+#include "media/base/test_helpers.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/file_data_source.h"
@@ -87,8 +87,9 @@ class FFmpegDemuxerTest : public testing::Test {
void InitializeDemuxer() {
EXPECT_CALL(host_, SetDuration(_));
- demuxer_->Initialize(&host_, NewStatusCB(PIPELINE_OK));
- message_loop_.Run();
+ WaitableMessageLoopEvent event;
+ demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(PIPELINE_OK);
}
MOCK_METHOD2(OnReadDoneCalled, void(int, int64));
@@ -122,18 +123,6 @@ class FFmpegDemuxerTest : public testing::Test {
location, size, timestampInMicroseconds);
}
- PipelineStatusCB NewStatusCB(PipelineStatus expected) {
- return base::Bind(&FFmpegDemuxerTest::OnStatusDone,
- base::Unretained(this), expected);
- }
-
- void OnStatusDone(PipelineStatus expected, PipelineStatus status) {
- EXPECT_EQ(expected, status);
-
- DCHECK_EQ(&message_loop_, MessageLoop::current());
- message_loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
- }
-
// Accessor to demuxer internals.
void set_duration_known(bool duration_known) {
demuxer_->duration_known_ = duration_known;
@@ -192,8 +181,9 @@ class FFmpegDemuxerTest : public testing::Test {
TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
// Simulate avformat_open_input() failing.
CreateDemuxer("ten_byte_file");
- demuxer_->Initialize(&host_, NewStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
- message_loop_.Run();
+ WaitableMessageLoopEvent event;
+ demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN);
}
// TODO(acolwell): Uncomment this test when we discover a file that passes
@@ -209,15 +199,17 @@ TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
// Open a file with no streams whatsoever.
CreateDemuxer("no_streams.webm");
- demuxer_->Initialize(&host_, NewStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- message_loop_.Run();
+ WaitableMessageLoopEvent event;
+ demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
}
TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) {
// Open a file containing streams but none of which are audio/video streams.
CreateDemuxer("no_audio_video.webm");
- demuxer_->Initialize(&host_, NewStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- message_loop_.Run();
+ WaitableMessageLoopEvent event;
+ demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
}
TEST_F(FFmpegDemuxerTest, Initialize_Successful) {
@@ -380,9 +372,10 @@ TEST_F(FFmpegDemuxerTest, Seek) {
message_loop_.Run();
// Issue a simple forward seek, which should discard queued packets.
+ WaitableMessageLoopEvent event;
demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
- NewStatusCB(PIPELINE_OK));
- message_loop_.Run();
+ event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(PIPELINE_OK);
// Audio read #1.
audio->Read(NewReadCB(FROM_HERE, 145, 803000));
@@ -553,9 +546,10 @@ TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) {
message_loop_.Run();
// Issue a simple forward seek, which should discard queued packets.
+ WaitableMessageLoopEvent event;
demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000),
- NewStatusCB(PIPELINE_OK));
- message_loop_.Run();
+ event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(PIPELINE_OK);
// Audio read #1.
audio->Read(NewReadCB(FROM_HERE, 40, 2403000));
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index ba6e114..309f08f 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -14,9 +14,9 @@
#include "media/base/decrypt_config.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/limits.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
#include "media/base/test_data_util.h"
+#include "media/base/test_helpers.h"
#include "media/base/video_decoder.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
diff --git a/media/filters/file_data_source_unittest.cc b/media/filters/file_data_source_unittest.cc
index ac170a7..d7eaad0 100644
--- a/media/filters/file_data_source_unittest.cc
+++ b/media/filters/file_data_source_unittest.cc
@@ -9,8 +9,8 @@
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/utf_string_conversions.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_data_source_host.h"
+#include "media/base/test_helpers.h"
#include "media/filters/file_data_source.h"
using ::testing::NiceMock;
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
index 2e6cc12..90f42fe 100644
--- a/media/filters/video_renderer_base_unittest.cc
+++ b/media/filters/video_renderer_base_unittest.cc
@@ -2,21 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <algorithm>
-
#include "base/bind.h"
#include "base/callback.h"
+#include "base/callback_helpers.h"
+#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
-#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/test_timeouts.h"
+#include "base/timer.h"
#include "media/base/data_buffer.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/limits.h"
-#include "media/base/mock_callback.h"
#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
#include "media/base/video_frame.h"
#include "media/filters/video_renderer_base.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,26 +30,17 @@ using ::testing::StrictMock;
namespace media {
-static const int kFrameDuration = 10;
-static const int kVideoDuration = kFrameDuration * 100;
-static const int kEndOfStream = -1;
+static const int kFrameDurationInMs = 10;
+static const int kVideoDurationInMs = kFrameDurationInMs * 100;
static const gfx::Size kNaturalSize(16u, 16u);
class VideoRendererBaseTest : public ::testing::Test {
public:
VideoRendererBaseTest()
: decoder_(new MockVideoDecoder()),
- demuxer_stream_(new MockDemuxerStream()),
- cv_(&lock_),
- event_(false, false),
- timeout_(TestTimeouts::action_timeout()),
- prerolling_(false),
- next_frame_timestamp_(0),
- paint_cv_(&lock_),
- paint_was_called_(false),
- should_queue_read_cb_(false) {
+ demuxer_stream_(new MockDemuxerStream()) {
renderer_ = new VideoRendererBase(
- base::Bind(&VideoRendererBaseTest::Paint, base::Unretained(this)),
+ base::Bind(&VideoRendererBaseTest::OnPaint, base::Unretained(this)),
base::Bind(&VideoRendererBaseTest::OnSetOpaque, base::Unretained(this)),
true);
@@ -65,36 +54,28 @@ class VideoRendererBaseTest : public ::testing::Test {
.Times(AnyNumber());
EXPECT_CALL(*this, OnTimeUpdate(_))
.Times(AnyNumber());
+ EXPECT_CALL(*this, OnPaint())
+ .Times(AnyNumber());
EXPECT_CALL(*this, OnSetOpaque(_))
.Times(AnyNumber());
}
- virtual ~VideoRendererBaseTest() {
- read_queue_.clear();
-
- if (renderer_) {
- Stop();
- }
- }
+ virtual ~VideoRendererBaseTest() {}
// Callbacks passed into VideoRendererBase().
+ MOCK_CONST_METHOD0(OnPaint, void());
MOCK_CONST_METHOD1(OnSetOpaque, void(bool));
// Callbacks passed into Initialize().
MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta));
MOCK_METHOD1(OnNaturalSizeChanged, void(const gfx::Size&));
- MOCK_METHOD0(OnEnded, void());
- MOCK_METHOD1(OnError, void(PipelineStatus));
void Initialize() {
- Initialize(kVideoDuration);
+ InitializeWithDuration(kVideoDurationInMs);
}
- void Initialize(int duration) {
- duration_ = duration;
-
- // TODO(scherkus): really, really, really need to inject a thread into
- // VideoRendererBase... it makes mocking much harder.
+ void InitializeWithDuration(int duration_ms) {
+ duration_ = base::TimeDelta::FromMilliseconds(duration_ms);
// Monitor reads from the decoder.
EXPECT_CALL(*decoder_, Read(_))
@@ -118,87 +99,69 @@ class VideoRendererBaseTest : public ::testing::Test {
EXPECT_CALL(*this, OnNaturalSizeChanged(kNaturalSize));
// Start prerolling.
- Preroll(0);
+ QueuePrerollFrames(0);
+ Preroll(0, PIPELINE_OK);
}
- void InitializeRenderer(PipelineStatus expected_status) {
+ void InitializeRenderer(PipelineStatus expected) {
+ SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected));
VideoRendererBase::VideoDecoderList decoders;
decoders.push_back(decoder_);
+
+ WaitableMessageLoopEvent event;
renderer_->Initialize(
demuxer_stream_,
decoders,
- NewExpectedStatusCB(expected_status),
+ event.GetPipelineStatusCB(),
base::Bind(&MockStatisticsCB::OnStatistics,
base::Unretained(&statistics_cb_object_)),
base::Bind(&VideoRendererBaseTest::OnTimeUpdate,
base::Unretained(this)),
base::Bind(&VideoRendererBaseTest::OnNaturalSizeChanged,
base::Unretained(this)),
- base::Bind(&VideoRendererBaseTest::OnEnded, base::Unretained(this)),
- base::Bind(&VideoRendererBaseTest::OnError, base::Unretained(this)),
+ ended_event_.GetClosure(),
+ error_event_.GetPipelineStatusCB(),
base::Bind(&VideoRendererBaseTest::GetTime, base::Unretained(this)),
base::Bind(&VideoRendererBaseTest::GetDuration,
base::Unretained(this)));
- }
-
- // Instead of immediately satisfying a decoder Read request, queue it up.
- void QueueReadCB() {
- should_queue_read_cb_ = true;
- }
-
- void SatisfyQueuedReadCB() {
- base::AutoLock l(lock_);
- CHECK(should_queue_read_cb_ && !queued_read_cb_.is_null());
- should_queue_read_cb_ = false;
- VideoDecoder::ReadCB read_cb(queued_read_cb_);
- queued_read_cb_.Reset();
- base::AutoUnlock u(lock_);
- read_cb.Run(VideoDecoder::kOk, VideoFrame::CreateEmptyFrame());
- }
-
- void StartPrerolling(int timestamp, PipelineStatus expected_status) {
- EXPECT_FALSE(prerolling_);
-
- next_frame_timestamp_ = 0;
- prerolling_ = true;
- renderer_->Preroll(base::TimeDelta::FromMilliseconds(timestamp),
- base::Bind(&VideoRendererBaseTest::OnPrerollComplete,
- base::Unretained(this), expected_status));
+ event.RunAndWaitForStatus(expected);
}
void Play() {
SCOPED_TRACE("Play()");
- renderer_->Play(NewWaitableClosure());
- WaitForClosure();
+ WaitableMessageLoopEvent event;
+ renderer_->Play(event.GetClosure());
+ event.RunAndWait();
}
- // Preroll to the given timestamp.
- //
- // Use |kEndOfStream| to preroll end of stream frames.
- void Preroll(int timestamp) {
- SCOPED_TRACE(base::StringPrintf("Preroll(%d)", timestamp));
- bool end_of_stream = (timestamp == kEndOfStream);
- int preroll_timestamp = end_of_stream ? 0 : timestamp;
- StartPrerolling(preroll_timestamp, PIPELINE_OK);
- FinishPrerolling(end_of_stream);
+ void Preroll(int timestamp_ms, PipelineStatus expected) {
+ SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected));
+ WaitableMessageLoopEvent event;
+ renderer_->Preroll(
+ base::TimeDelta::FromMilliseconds(timestamp_ms),
+ event.GetPipelineStatusCB());
+ event.RunAndWaitForStatus(expected);
}
void Pause() {
SCOPED_TRACE("Pause()");
- renderer_->Pause(NewWaitableClosure());
- WaitForClosure();
+ WaitableMessageLoopEvent event;
+ renderer_->Pause(event.GetClosure());
+ event.RunAndWait();
}
void Flush() {
SCOPED_TRACE("Flush()");
- renderer_->Flush(NewWaitableClosure());
- WaitForClosure();
+ WaitableMessageLoopEvent event;
+ renderer_->Flush(event.GetClosure());
+ event.RunAndWait();
}
void Stop() {
SCOPED_TRACE("Stop()");
- renderer_->Stop(NewWaitableClosure());
- WaitForClosure();
+ WaitableMessageLoopEvent event;
+ renderer_->Stop(event.GetClosure());
+ event.RunAndWait();
}
void Shutdown() {
@@ -207,122 +170,113 @@ class VideoRendererBaseTest : public ::testing::Test {
Stop();
}
- void DeliverNextFrame(bool end_of_stream) {
- base::AutoLock l(lock_);
- DeliverNextFrame_Locked(end_of_stream);
+ // Queues a VideoFrame with |next_frame_timestamp_|.
+ void QueueNextFrame() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ DCHECK_LT(next_frame_timestamp_.InMicroseconds(),
+ duration_.InMicroseconds());
+
+ scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
+ VideoFrame::RGB32, kNaturalSize, gfx::Rect(kNaturalSize), kNaturalSize,
+ next_frame_timestamp_);
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kOk, frame));
+ next_frame_timestamp_ +=
+ base::TimeDelta::FromMilliseconds(kFrameDurationInMs);
}
- // Delivers the next frame to the video renderer. If |end_of_stream|
- // is true then an "end or stream" frame will be returned. Otherwise
- // A frame with |next_frame_timestamp_| will be returned.
- void DeliverNextFrame_Locked(bool end_of_stream) {
- lock_.AssertAcquired();
-
- VideoDecoder::ReadCB read_cb;
- std::swap(read_cb, read_cb_);
-
- DCHECK_LT(next_frame_timestamp_, duration_);
- int timestamp = next_frame_timestamp_;
- next_frame_timestamp_ += kFrameDuration;
-
- // Unlock to deliver the frame to avoid re-entrancy issues.
- base::AutoUnlock ul(lock_);
- if (end_of_stream) {
- read_cb.Run(VideoDecoder::kOk, VideoFrame::CreateEmptyFrame());
- } else {
- read_cb.Run(VideoDecoder::kOk, CreateFrame(timestamp));
- }
+ void QueueEndOfStream() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kOk, VideoFrame::CreateEmptyFrame()));
}
- void DecoderError() {
- // Lock+swap to avoid re-entrancy issues.
- VideoDecoder::ReadCB read_cb;
- {
- base::AutoLock l(lock_);
- std::swap(read_cb, read_cb_);
- }
+ void QueueDecodeError() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ scoped_refptr<VideoFrame> null_frame;
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kDecodeError, null_frame));
+ }
- read_cb.Run(VideoDecoder::kDecodeError, NULL);
+ void QueueAbortedRead() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ scoped_refptr<VideoFrame> null_frame;
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kOk, null_frame));
}
- void AbortRead() {
- // Lock+swap to avoid re-entrancy issues.
- VideoDecoder::ReadCB read_cb;
- {
- base::AutoLock l(lock_);
- std::swap(read_cb, read_cb_);
+ void QueuePrerollFrames(int timestamp_ms) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ next_frame_timestamp_ = base::TimeDelta();
+ base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(timestamp_ms);
+ while (next_frame_timestamp_ < timestamp) {
+ QueueNextFrame();
}
- read_cb.Run(VideoDecoder::kOk, NULL);
- }
-
- void ExpectCurrentFrame(bool present) {
- scoped_refptr<VideoFrame> frame;
- renderer_->GetCurrentFrame(&frame);
- if (present) {
- EXPECT_TRUE(frame);
- } else {
- EXPECT_FALSE(frame);
+ // Queue the frame at |timestamp| plus additional ones for prerolling.
+ for (int i = 0; i < limits::kMaxVideoFrames; ++i) {
+ QueueNextFrame();
}
- renderer_->PutCurrentFrame(frame);
}
- void ExpectCurrentTimestamp(int timestamp) {
+ scoped_refptr<VideoFrame> GetCurrentFrame() {
scoped_refptr<VideoFrame> frame;
renderer_->GetCurrentFrame(&frame);
- EXPECT_EQ(timestamp, frame->GetTimestamp().InMilliseconds());
renderer_->PutCurrentFrame(frame);
+ return frame;
}
- base::Closure NewWaitableClosure() {
- return base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event_));
+ int GetCurrentTimestampInMs() {
+ scoped_refptr<VideoFrame> frame = GetCurrentFrame();
+ if (!frame)
+ return -1;
+ return frame->GetTimestamp().InMilliseconds();
}
- void WaitForClosure() {
- ASSERT_TRUE(event_.TimedWait(timeout_));
- event_.Reset();
+ void WaitForError(PipelineStatus expected) {
+ SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected));
+ error_event_.RunAndWaitForStatus(expected);
}
- // Creates a frame with given timestamp.
- scoped_refptr<VideoFrame> CreateFrame(int timestamp) {
- scoped_refptr<VideoFrame> frame =
- VideoFrame::CreateFrame(VideoFrame::RGB32, kNaturalSize,
- gfx::Rect(kNaturalSize), kNaturalSize,
- base::TimeDelta::FromMilliseconds(timestamp));
- return frame;
+ void WaitForEnded() {
+ SCOPED_TRACE("WaitForEnded()");
+ ended_event_.RunAndWait();
}
- // Advances clock to |timestamp| and waits for the frame at |timestamp| to get
- // rendered using |read_cb_| as the signal that the frame has rendered.
- void RenderFrame(int timestamp) {
- base::AutoLock l(lock_);
- time_ = base::TimeDelta::FromMilliseconds(timestamp);
- paint_was_called_ = false;
- if (read_cb_.is_null()) {
- cv_.TimedWait(timeout_);
- CHECK(!read_cb_.is_null()) << "Timed out waiting for read to occur.";
- }
- WaitForPaint_Locked();
- }
+ void WaitForPendingRead() {
+ SCOPED_TRACE("WaitForPendingRead()");
+ if (!read_cb_.is_null())
+ return;
- // Advances clock to |timestamp| (which should be the timestamp of the last
- // frame plus duration) and waits for the ended signal before returning.
- void RenderLastFrame(int timestamp) {
- EXPECT_CALL(*this, OnEnded())
- .WillOnce(Invoke(&event_, &base::WaitableEvent::Signal));
- {
- base::AutoLock l(lock_);
- time_ = base::TimeDelta::FromMilliseconds(timestamp);
- }
- CHECK(event_.TimedWait(timeout_)) << "Timed out waiting for ended signal.";
+ DCHECK(pending_read_cb_.is_null());
+
+ WaitableMessageLoopEvent event;
+ pending_read_cb_ = event.GetClosure();
+ event.RunAndWait();
+
+ DCHECK(!read_cb_.is_null());
+ DCHECK(pending_read_cb_.is_null());
}
- base::WaitableEvent* event() { return &event_; }
- const base::TimeDelta& timeout() { return timeout_; }
+ void SatisfyPendingRead() {
+ CHECK(!read_cb_.is_null());
+ CHECK(!decode_results_.empty());
+
+ base::Closure closure = base::Bind(
+ read_cb_, decode_results_.front().first,
+ decode_results_.front().second);
- void VerifyNotPrerolling() {
+ read_cb_.Reset();
+ decode_results_.pop_front();
+
+ message_loop_.PostTask(FROM_HERE, closure);
+ }
+
+ void AdvanceTimeInMs(int time_ms) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
base::AutoLock l(lock_);
- ASSERT_FALSE(prerolling_);
+ time_ += base::TimeDelta::FromMilliseconds(time_ms);
+ DCHECK_LE(time_.InMicroseconds(), duration_.InMicroseconds());
}
protected:
@@ -332,119 +286,80 @@ class VideoRendererBaseTest : public ::testing::Test {
scoped_refptr<MockDemuxerStream> demuxer_stream_;
MockStatisticsCB statistics_cb_object_;
- // Receives all the buffers that renderer had provided to |decoder_|.
- std::deque<scoped_refptr<VideoFrame> > read_queue_;
-
private:
- // Called by VideoRendererBase for accessing the current time.
base::TimeDelta GetTime() {
base::AutoLock l(lock_);
return time_;
}
base::TimeDelta GetDuration() {
- return base::TimeDelta::FromMilliseconds(duration_);
+ return duration_;
}
- // Called by VideoRendererBase when it wants a frame.
- void FrameRequested(const VideoDecoder::ReadCB& callback) {
- base::AutoLock l(lock_);
- if (should_queue_read_cb_) {
- CHECK(queued_read_cb_.is_null());
- queued_read_cb_ = callback;
+ void FrameRequested(const VideoDecoder::ReadCB& read_cb) {
+ // TODO(scherkus): Make VideoRendererBase call on right thread.
+ if (&message_loop_ != MessageLoop::current()) {
+ message_loop_.PostTask(FROM_HERE, base::Bind(
+ &VideoRendererBaseTest::FrameRequested, base::Unretained(this),
+ read_cb));
return;
}
- CHECK(read_cb_.is_null());
- read_cb_ = callback;
- cv_.Signal();
- }
- void FlushRequested(const base::Closure& callback) {
- // Lock+swap to avoid re-entrancy issues.
- VideoDecoder::ReadCB read_cb;
- {
- base::AutoLock l(lock_);
- std::swap(read_cb, read_cb_);
- }
+ CHECK(read_cb_.is_null());
+ read_cb_ = read_cb;
- // Abort pending read.
- if (!read_cb.is_null())
- read_cb.Run(VideoDecoder::kOk, NULL);
+ // Wake up WaitForPendingRead() if needed.
+ if (!pending_read_cb_.is_null())
+ base::ResetAndReturn(&pending_read_cb_).Run();
- callback.Run();
- }
+ if (decode_results_.empty())
+ return;
- void OnPrerollComplete(PipelineStatus expected_status,
- PipelineStatus status) {
- base::AutoLock l(lock_);
- EXPECT_EQ(status, expected_status);
- EXPECT_TRUE(prerolling_);
- prerolling_ = false;
- cv_.Signal();
+ SatisfyPendingRead();
}
- void FinishPrerolling(bool end_of_stream) {
- // Satisfy the read requests. The callback must be executed in order
- // to exit the loop since VideoRendererBase can read a few extra frames
- // after |timestamp| in order to preroll.
- base::AutoLock l(lock_);
- EXPECT_TRUE(prerolling_);
- paint_was_called_ = false;
- while (prerolling_) {
- if (!read_cb_.is_null()) {
- DeliverNextFrame_Locked(end_of_stream);
- } else {
- // We want to wait iff we're still prerolling but have no pending read.
- cv_.TimedWait(timeout_);
- CHECK(!prerolling_ || !read_cb_.is_null())
- << "Timed out waiting for preroll or read to occur.";
- }
+ void FlushRequested(const base::Closure& callback) {
+ // TODO(scherkus): Make VideoRendererBase call on right thread.
+ if (&message_loop_ != MessageLoop::current()) {
+ message_loop_.PostTask(FROM_HERE, base::Bind(
+ &VideoRendererBaseTest::FlushRequested, base::Unretained(this),
+ callback));
+ return;
}
- EXPECT_TRUE(read_cb_.is_null());
- WaitForPaint_Locked();
- }
+ decode_results_.clear();
+ if (!read_cb_.is_null()) {
+ QueueAbortedRead();
+ SatisfyPendingRead();
+ }
- void Paint() {
- base::AutoLock l(lock_);
- paint_was_called_ = true;
- paint_cv_.Signal();
+ message_loop_.PostTask(FROM_HERE, callback);
}
- void WaitForPaint_Locked() {
- lock_.AssertAcquired();
- if (paint_was_called_)
- return;
- paint_cv_.TimedWait(timeout_);
- EXPECT_TRUE(paint_was_called_);
- }
+ MessageLoop message_loop_;
+ // Used to protect |time_|.
base::Lock lock_;
- base::ConditionVariable cv_;
- base::WaitableEvent event_;
- base::TimeDelta timeout_;
+ base::TimeDelta time_;
- // Used in conjunction with |lock_| and |cv_| for satisfying reads.
- bool prerolling_;
+ // Used for satisfying reads.
VideoDecoder::ReadCB read_cb_;
- int next_frame_timestamp_;
- int duration_;
- base::TimeDelta time_;
+ base::TimeDelta next_frame_timestamp_;
+ base::TimeDelta duration_;
- // Used in conjunction with |lock_| to wait for Paint() calls.
- base::ConditionVariable paint_cv_;
- bool paint_was_called_;
+ WaitableMessageLoopEvent error_event_;
+ WaitableMessageLoopEvent ended_event_;
+ base::Closure pending_read_cb_;
- // Holding queue for Read callbacks for exercising delayed demux/decode.
- bool should_queue_read_cb_;
- VideoDecoder::ReadCB queued_read_cb_;
+ std::deque<std::pair<
+ VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_;
DISALLOW_COPY_AND_ASSIGN(VideoRendererBaseTest);
};
TEST_F(VideoRendererBaseTest, Initialize) {
Initialize();
- ExpectCurrentTimestamp(0);
+ EXPECT_EQ(0, GetCurrentTimestampInMs());
Shutdown();
}
@@ -458,68 +373,61 @@ TEST_F(VideoRendererBaseTest, EndOfStream_DefaultFrameDuration) {
Initialize();
Play();
- // Finish rendering up to the next-to-last frame.
- int timestamp = kFrameDuration;
- for (int i = 1; i < limits::kMaxVideoFrames; ++i) {
- RenderFrame(timestamp);
- timestamp += kFrameDuration;
- }
-
- // Deliver the end of stream frame.
- DeliverNextFrame(true);
-
// Verify that the ended callback fires when the default last frame duration
// has elapsed.
- int end_timestamp =
- timestamp + VideoRendererBase::kMaxLastFrameDuration().InMilliseconds();
- EXPECT_LT(end_timestamp, kVideoDuration);
- RenderLastFrame(end_timestamp);
+ int end_timestamp = kFrameDurationInMs * limits::kMaxVideoFrames +
+ VideoRendererBase::kMaxLastFrameDuration().InMilliseconds();
+ EXPECT_LT(end_timestamp, kVideoDurationInMs);
+
+ QueueEndOfStream();
+ AdvanceTimeInMs(end_timestamp);
+ WaitForEnded();
Shutdown();
}
TEST_F(VideoRendererBaseTest, EndOfStream_ClipDuration) {
- int duration = kVideoDuration + kFrameDuration / 2;
- Initialize(duration);
+ int duration = kVideoDurationInMs + kFrameDurationInMs / 2;
+ InitializeWithDuration(duration);
Play();
// Render all frames except for the last |limits::kMaxVideoFrames| frames
// and deliver all the frames between the start and |duration|. The preroll
// inside Initialize() makes this a little confusing, but |timestamp| is
- // the current render time and DeliverNextFrame() delivers a frame with a
- // timestamp that is |timestamp| + limits::kMaxVideoFrames * kFrameDuration.
- int timestamp = kFrameDuration;
- int end_timestamp = duration - limits::kMaxVideoFrames * kFrameDuration;
- for (; timestamp < end_timestamp; timestamp += kFrameDuration) {
- RenderFrame(timestamp);
- DeliverNextFrame(false);
+ // the current render time and QueueNextFrame() delivers a frame with a
+ // timestamp that is |timestamp| + limits::kMaxVideoFrames *
+ // kFrameDurationInMs.
+ int timestamp = kFrameDurationInMs;
+ int end_timestamp = duration - limits::kMaxVideoFrames * kFrameDurationInMs;
+ for (; timestamp < end_timestamp; timestamp += kFrameDurationInMs) {
+ QueueNextFrame();
}
- // Render the next frame so that a Read() will get requested.
- RenderFrame(timestamp);
-
- // Deliver the end of stream frame and wait for the last frame to be rendered.
- DeliverNextFrame(true);
- RenderLastFrame(duration);
+ // Queue the end of stream frame and wait for the last frame to be rendered.
+ QueueEndOfStream();
+ AdvanceTimeInMs(duration);
+ WaitForEnded();
Shutdown();
}
-TEST_F(VideoRendererBaseTest, DecoderError) {
+TEST_F(VideoRendererBaseTest, DecodeError_Playing) {
Initialize();
Play();
- RenderFrame(kFrameDuration);
- EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE));
- DecoderError();
+
+ QueueDecodeError();
+ AdvanceTimeInMs(kVideoDurationInMs);
+ WaitForError(PIPELINE_ERROR_DECODE);
Shutdown();
}
-TEST_F(VideoRendererBaseTest, DecoderErrorDuringPreroll) {
+TEST_F(VideoRendererBaseTest, DecodeError_DuringPreroll) {
Initialize();
Pause();
Flush();
- StartPrerolling(kFrameDuration * 6, PIPELINE_ERROR_DECODE);
- DecoderError();
+
+ QueueDecodeError();
+ Preroll(kFrameDurationInMs * 6, PIPELINE_ERROR_DECODE);
Shutdown();
}
@@ -527,8 +435,10 @@ TEST_F(VideoRendererBaseTest, Preroll_Exact) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDurationInMs * 6);
+
+ Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
+ EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
Shutdown();
}
@@ -536,8 +446,10 @@ TEST_F(VideoRendererBaseTest, Preroll_RightBefore) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6 - 1);
- ExpectCurrentTimestamp(kFrameDuration * 5);
+ QueuePrerollFrames(kFrameDurationInMs * 6);
+
+ Preroll(kFrameDurationInMs * 6 - 1, PIPELINE_OK);
+ EXPECT_EQ(kFrameDurationInMs * 5, GetCurrentTimestampInMs());
Shutdown();
}
@@ -545,21 +457,23 @@ TEST_F(VideoRendererBaseTest, Preroll_RightAfter) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6 + 1);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDurationInMs * 6);
+
+ Preroll(kFrameDurationInMs * 6 + 1, PIPELINE_OK);
+ EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
Shutdown();
}
TEST_F(VideoRendererBaseTest, GetCurrentFrame_Initialized) {
Initialize();
- ExpectCurrentFrame(true); // Due to prerolling.
+ EXPECT_TRUE(GetCurrentFrame()); // Due to prerolling.
Shutdown();
}
TEST_F(VideoRendererBaseTest, GetCurrentFrame_Playing) {
Initialize();
Play();
- ExpectCurrentFrame(true);
+ EXPECT_TRUE(GetCurrentFrame());
Shutdown();
}
@@ -567,7 +481,7 @@ TEST_F(VideoRendererBaseTest, GetCurrentFrame_Paused) {
Initialize();
Play();
Pause();
- ExpectCurrentFrame(true);
+ EXPECT_TRUE(GetCurrentFrame());
Shutdown();
}
@@ -576,7 +490,7 @@ TEST_F(VideoRendererBaseTest, GetCurrentFrame_Flushed) {
Play();
Pause();
Flush();
- ExpectCurrentFrame(false);
+ EXPECT_FALSE(GetCurrentFrame());
Shutdown();
}
@@ -593,14 +507,13 @@ TEST_F(VideoRendererBaseTest, MAYBE_GetCurrentFrame_EndOfStream) {
Flush();
// Preroll only end of stream frames.
- Preroll(kEndOfStream);
- ExpectCurrentFrame(false);
+ QueueEndOfStream();
+ Preroll(0, PIPELINE_OK);
+ EXPECT_FALSE(GetCurrentFrame());
// Start playing, we should immediately get notified of end of stream.
- EXPECT_CALL(*this, OnEnded())
- .WillOnce(Invoke(event(), &base::WaitableEvent::Signal));
Play();
- CHECK(event()->TimedWait(timeout())) << "Timed out waiting for ended signal.";
+ WaitForEnded();
Shutdown();
}
@@ -608,14 +521,14 @@ TEST_F(VideoRendererBaseTest, MAYBE_GetCurrentFrame_EndOfStream) {
TEST_F(VideoRendererBaseTest, GetCurrentFrame_Shutdown) {
Initialize();
Shutdown();
- ExpectCurrentFrame(false);
+ EXPECT_FALSE(GetCurrentFrame());
}
// Stop() is called immediately during an error.
TEST_F(VideoRendererBaseTest, GetCurrentFrame_Error) {
Initialize();
Stop();
- ExpectCurrentFrame(false);
+ EXPECT_FALSE(GetCurrentFrame());
}
// Verify that shutdown can only proceed after we return the current frame.
@@ -631,11 +544,12 @@ TEST_F(VideoRendererBaseTest, Shutdown_DuringPaint) {
Pause();
// Start flushing -- it won't complete until we return the frame.
- renderer_->Flush(NewWaitableClosure());
+ WaitableMessageLoopEvent event;
+ renderer_->Flush(event.GetClosure());
// Return the frame and wait.
renderer_->PutCurrentFrame(frame);
- WaitForClosure();
+ event.RunAndWait();
Stop();
}
@@ -643,28 +557,37 @@ TEST_F(VideoRendererBaseTest, Shutdown_DuringPaint) {
// Verify that a late decoder response doesn't break invariants in the renderer.
TEST_F(VideoRendererBaseTest, StopDuringOutstandingRead) {
Initialize();
- Pause();
- Flush();
- QueueReadCB();
- StartPrerolling(kFrameDuration * 6, PIPELINE_OK); // Force-decode some more.
- renderer_->Stop(NewWaitableClosure());
- SatisfyQueuedReadCB();
- WaitForClosure(); // Finish the Stop().
+ Play();
+
+ // Advance time a bit to trigger a Read().
+ AdvanceTimeInMs(kFrameDurationInMs);
+ WaitForPendingRead();
+
+ WaitableMessageLoopEvent event;
+ renderer_->Stop(event.GetClosure());
+
+ QueueEndOfStream();
+ SatisfyPendingRead();
+
+ event.RunAndWait();
}
TEST_F(VideoRendererBaseTest, AbortPendingRead_Playing) {
Initialize();
Play();
- // Render a frame to trigger a Read().
- RenderFrame(kFrameDuration);
+ // Advance time a bit to trigger a Read().
+ AdvanceTimeInMs(kFrameDurationInMs);
+ WaitForPendingRead();
- AbortRead();
+ QueueAbortedRead();
+ SatisfyPendingRead();
Pause();
Flush();
- Preroll(kFrameDuration * 6);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDurationInMs * 6);
+ Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
+ EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
Shutdown();
}
@@ -672,8 +595,9 @@ TEST_F(VideoRendererBaseTest, AbortPendingRead_Flush) {
Initialize();
Play();
- // Render a frame to trigger a Read().
- RenderFrame(kFrameDuration);
+ // Advance time a bit to trigger a Read().
+ AdvanceTimeInMs(kFrameDurationInMs);
+ WaitForPendingRead();
Pause();
Flush();
@@ -684,9 +608,9 @@ TEST_F(VideoRendererBaseTest, AbortPendingRead_Preroll) {
Initialize();
Pause();
Flush();
- StartPrerolling(kFrameDuration * 6, PIPELINE_OK);
- AbortRead();
- VerifyNotPrerolling();
+
+ QueueAbortedRead();
+ Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
Shutdown();
}
@@ -696,6 +620,8 @@ TEST_F(VideoRendererBaseTest, VideoDecoder_InitFailure) {
EXPECT_CALL(*decoder_, Initialize(_, _, _))
.WillOnce(RunCallback<1>(PIPELINE_ERROR_DECODE));
InitializeRenderer(PIPELINE_ERROR_DECODE);
+
+ Stop();
}
} // namespace media
diff --git a/media/media.gyp b/media/media.gyp
index 963ee56..b061d7a 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -841,14 +841,14 @@
'base/gmock_callback_support.h',
'base/mock_audio_renderer_sink.cc',
'base/mock_audio_renderer_sink.h',
- 'base/mock_callback.cc',
- 'base/mock_callback.h',
'base/mock_data_source_host.cc',
'base/mock_data_source_host.h',
'base/mock_demuxer_host.cc',
'base/mock_demuxer_host.h',
'base/mock_filters.cc',
'base/mock_filters.h',
+ 'base/test_helpers.cc',
+ 'base/test_helpers.h',
],
},
],