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

Unified Diff: media/filters/video_renderer_base_unittest.cc

Issue 11316293: Replace WaitableEvents and ConditionalVariables in VideoRendererBase tests with MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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 side-by-side diff with in-line comments
Download patch
« media/base/mock_callback.h ('K') | « media/filters/ffmpeg_demuxer_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/video_renderer_base_unittest.cc
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
index 2e6cc1219fe39d2e69014d36060bfadf4ef796a6..2db0fb61461ec0bed97dcebc48bec07981834f2e 100644
--- a/media/filters/video_renderer_base_unittest.cc
+++ b/media/filters/video_renderer_base_unittest.cc
@@ -2,16 +2,16 @@
// 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/bind_to_loop.h"
#include "media/base/data_buffer.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/limits.h"
@@ -34,24 +34,79 @@ namespace media {
static const int kFrameDuration = 10;
static const int kVideoDuration = kFrameDuration * 100;
-static const int kEndOfStream = -1;
static const gfx::Size kNaturalSize(16u, 16u);
+class WaitableMessageLoopEvent {
scherkus (not reviewing) 2012/12/05 00:03:46 if we like this approach I'm going to move this in
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 SGTM
+ public:
+ WaitableMessageLoopEvent()
+ : message_loop_(MessageLoop::current()),
+ signaled_(false),
+ status_(PIPELINE_OK) {
+ }
+
+ ~WaitableMessageLoopEvent() {}
+
+ void Reset() { signaled_ = false; }
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 nit: Should status_ be reset as well?
scherkus (not reviewing) 2012/12/05 21:52:03 Done.
+ bool IsSignaled() { return signaled_; }
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 remove since it isn't being used.
scherkus (not reviewing) 2012/12/05 21:52:03 Done.
+
+ // Returns a thread-safe closure that will signal |this| when executed.
+ base::Closure GetClosure() {
+ return BindToLoop(message_loop_->message_loop_proxy(), base::Bind(
+ &WaitableMessageLoopEvent::OnCallback, base::Unretained(this),
+ PIPELINE_OK));
+ }
+
+ PipelineStatusCB GetPipelineStatusCB() {
+ return BindToLoop(message_loop_->message_loop_proxy(), base::Bind(
+ &WaitableMessageLoopEvent::OnCallback, base::Unretained(this)));
+ }
+
+ // Convenience function for running the message loop until |this| has been
+ // signaled.
+ void RunAndWait() {
+ RunAndWaitForStatus(PIPELINE_OK);
+ }
+
+ void RunAndWaitForStatus(PipelineStatus expected) {
+ base::Timer timer(false, false);
+ timer.Start(FROM_HERE, TestTimeouts::action_timeout(), base::Bind(
+ &WaitableMessageLoopEvent::OnTimeout, base::Unretained(this)));
+
+ DCHECK(!signaled_);
+ message_loop_->Run();
scherkus (not reviewing) 2012/12/05 00:03:46 this is now the only place where a message loop is
+ DCHECK(signaled_);
+ EXPECT_EQ(expected, status_);
+ }
+
+ private:
+ void OnCallback(PipelineStatus status) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ signaled_ = true;
+ status_ = status;
+ message_loop_->QuitWhenIdle();
scherkus (not reviewing) 2012/12/05 00:03:46 here + OnTimeout() are now the only places where a
+ }
+
+ void OnTimeout() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ ADD_FAILURE() << "Timed out waiting for message loop to quit";
+ message_loop_->QuitWhenIdle();
+ }
+
+ MessageLoop* message_loop_;
+ bool signaled_;
+ PipelineStatus status_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaitableMessageLoopEvent);
+};
+
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) {
+ next_frame_timestamp_(0) {
renderer_ = new VideoRendererBase(
- base::Bind(&VideoRendererBaseTest::Paint, base::Unretained(this)),
+ base::Bind(&VideoRendererBaseTest::OnPaint, base::Unretained(this)),
scherkus (not reviewing) 2012/12/05 00:03:46 we no longer use paints to signal anything and ins
base::Bind(&VideoRendererBaseTest::OnSetOpaque, base::Unretained(this)),
true);
@@ -65,26 +120,21 @@ 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);
@@ -93,9 +143,6 @@ class VideoRendererBaseTest : public ::testing::Test {
void Initialize(int duration) {
duration_ = duration;
- // TODO(scherkus): really, really, really need to inject a thread into
- // VideoRendererBase... it makes mocking much harder.
-
// Monitor reads from the decoder.
EXPECT_CALL(*decoder_, Read(_))
.WillRepeatedly(Invoke(this, &VideoRendererBaseTest::FrameRequested));
@@ -118,87 +165,70 @@ 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("Initialize(%d)", expected));
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 nit: s/Initialize/InitializeRenderer/ ?
scherkus (not reviewing) 2012/12/05 21:52:03 Done.
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, PipelineStatus expected) {
+ SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp, expected));
+ WaitableMessageLoopEvent event;
+ renderer_->Preroll(
+ base::TimeDelta::FromMilliseconds(timestamp),
+ 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 +237,79 @@ class VideoRendererBaseTest : public ::testing::Test {
Stop();
}
- void DeliverNextFrame(bool end_of_stream) {
- base::AutoLock l(lock_);
- DeliverNextFrame_Locked(end_of_stream);
- }
-
- // 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_);
+ // Queues a VideoFrame with |next_frame_timestamp_|.
+ void QueueNextFrame() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
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));
- }
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kOk, CreateFrame(timestamp)));
}
- void DecoderError() {
- // Lock+swap to avoid re-entrancy issues.
- VideoDecoder::ReadCB read_cb;
- {
- base::AutoLock l(lock_);
- std::swap(read_cb, read_cb_);
- }
-
- read_cb.Run(VideoDecoder::kDecodeError, NULL);
+ void QueueEndOfStream() {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ decode_results_.push_back(std::make_pair(
+ VideoDecoder::kOk, VideoFrame::CreateEmptyFrame()));
}
- void AbortRead() {
- // 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::kOk, 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 ExpectCurrentFrame(bool present) {
- scoped_refptr<VideoFrame> frame;
- renderer_->GetCurrentFrame(&frame);
- if (present) {
- EXPECT_TRUE(frame);
- } else {
- EXPECT_FALSE(frame);
+ void QueuePrerollFrames(int timestamp) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+ next_frame_timestamp_ = 0;
+ while (next_frame_timestamp_ < timestamp) {
+ QueueNextFrame();
+ }
+
+ // 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 GetCurrentTimestamp() {
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 nit: s/GetCurrentTimestamp/GetCurrentTimestampInMs
scherkus (not reviewing) 2012/12/05 21:52:03 Done.
+ 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) {
+ void SetTime(int timestamp) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
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();
- }
-
- // 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.";
- }
-
- base::WaitableEvent* event() { return &event_; }
- const base::TimeDelta& timeout() { return timeout_; }
-
- void VerifyNotPrerolling() {
- base::AutoLock l(lock_);
- ASSERT_FALSE(prerolling_);
}
protected:
@@ -332,11 +319,15 @@ 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.
+ 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;
+ }
+
base::TimeDelta GetTime() {
base::AutoLock l(lock_);
return time_;
@@ -346,105 +337,68 @@ class VideoRendererBaseTest : public ::testing::Test {
return base::TimeDelta::FromMilliseconds(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;
- return;
- }
+ void FrameRequested(const VideoDecoder::ReadCB& read_cb) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
+
CHECK(read_cb_.is_null());
- read_cb_ = callback;
- cv_.Signal();
+ read_cb_ = read_cb;
+
+ if (decode_results_.empty())
+ return;
+
+ SatisfyPendingRead();
}
- 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_);
- }
+ void SatisfyPendingRead() {
+ CHECK(!read_cb_.is_null());
+ CHECK(!decode_results_.empty());
- // Abort pending read.
- if (!read_cb.is_null())
- read_cb.Run(VideoDecoder::kOk, NULL);
+ base::Closure closure = base::Bind(
+ read_cb_, decode_results_.front().first,
+ decode_results_.front().second);
- callback.Run();
- }
+ read_cb_.Reset();
+ decode_results_.pop_front();
- void OnPrerollComplete(PipelineStatus expected_status,
- PipelineStatus status) {
- base::AutoLock l(lock_);
- EXPECT_EQ(status, expected_status);
- EXPECT_TRUE(prerolling_);
- prerolling_ = false;
- cv_.Signal();
+ message_loop_.PostTask(FROM_HERE, closure);
}
- 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.";
- }
- }
- EXPECT_TRUE(read_cb_.is_null());
- WaitForPaint_Locked();
- }
+ void FlushRequested(const base::Closure& callback) {
+ DCHECK_EQ(&message_loop_, MessageLoop::current());
- void Paint() {
- base::AutoLock l(lock_);
- paint_was_called_ = true;
- paint_cv_.Signal();
- }
+ decode_results_.clear();
+ if (!read_cb_.is_null()) {
+ QueueAbortedRead();
+ SatisfyPendingRead();
+ }
- void WaitForPaint_Locked() {
- lock_.AssertAcquired();
- if (paint_was_called_)
- return;
- paint_cv_.TimedWait(timeout_);
- EXPECT_TRUE(paint_was_called_);
+ message_loop_.PostTask(FROM_HERE, callback);
}
+ 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_;
- // Used in conjunction with |lock_| to wait for Paint() calls.
- base::ConditionVariable paint_cv_;
- bool paint_was_called_;
+ WaitableMessageLoopEvent error_event_;
+ WaitableMessageLoopEvent ended_event_;
- // 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, GetCurrentTimestamp());
Shutdown();
}
@@ -458,22 +412,15 @@ 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();
+ int end_timestamp = kFrameDuration * limits::kMaxVideoFrames +
+ VideoRendererBase::kMaxLastFrameDuration().InMilliseconds();
EXPECT_LT(end_timestamp, kVideoDuration);
- RenderLastFrame(end_timestamp);
+
+ QueueEndOfStream();
+ SetTime(end_timestamp);
+ WaitForEnded();
Shutdown();
}
@@ -486,40 +433,39 @@ TEST_F(VideoRendererBaseTest, EndOfStream_ClipDuration) {
// 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
+ // the current render time and QueueNextFrame() 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);
+ 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();
+ SetTime(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();
+ SetTime(kVideoDuration);
+ 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(kFrameDuration * 6, PIPELINE_ERROR_DECODE);
Shutdown();
}
@@ -527,8 +473,10 @@ TEST_F(VideoRendererBaseTest, Preroll_Exact) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDuration * 6);
+
+ Preroll(kFrameDuration * 6, PIPELINE_OK);
+ EXPECT_EQ(kFrameDuration * 6, GetCurrentTimestamp());
Shutdown();
}
@@ -536,8 +484,10 @@ TEST_F(VideoRendererBaseTest, Preroll_RightBefore) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6 - 1);
- ExpectCurrentTimestamp(kFrameDuration * 5);
+ QueuePrerollFrames(kFrameDuration * 6);
+
+ Preroll(kFrameDuration * 6 - 1, PIPELINE_OK);
+ EXPECT_EQ(kFrameDuration * 5, GetCurrentTimestamp());
Shutdown();
}
@@ -545,21 +495,23 @@ TEST_F(VideoRendererBaseTest, Preroll_RightAfter) {
Initialize();
Pause();
Flush();
- Preroll(kFrameDuration * 6 + 1);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDuration * 6);
+
+ Preroll(kFrameDuration * 6 + 1, PIPELINE_OK);
+ EXPECT_EQ(kFrameDuration * 6, GetCurrentTimestamp());
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 +519,7 @@ TEST_F(VideoRendererBaseTest, GetCurrentFrame_Paused) {
Initialize();
Play();
Pause();
- ExpectCurrentFrame(true);
+ EXPECT_TRUE(GetCurrentFrame());
Shutdown();
}
@@ -576,7 +528,7 @@ TEST_F(VideoRendererBaseTest, GetCurrentFrame_Flushed) {
Play();
Pause();
Flush();
- ExpectCurrentFrame(false);
+ EXPECT_FALSE(GetCurrentFrame());
Shutdown();
}
@@ -593,14 +545,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 +559,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 +582,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();
}
@@ -645,26 +597,28 @@ 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().
+ QueuePrerollFrames(kFrameDuration * 6);
+ Preroll(kFrameDuration * 6, PIPELINE_OK); // Force-decode some more.
+
+ WaitableMessageLoopEvent event;
+ renderer_->Stop(event.GetClosure());
+ QueueEndOfStream();
scherkus (not reviewing) 2012/12/05 00:03:46 I need to think more about this test -- I don't th
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 Yeah. You need to make sure there is a pending rea
+ event.RunAndWait();
}
TEST_F(VideoRendererBaseTest, AbortPendingRead_Playing) {
Initialize();
Play();
- // Render a frame to trigger a Read().
- RenderFrame(kFrameDuration);
-
- AbortRead();
+ // Advance time a bit to trigger a Read().
+ SetTime(kFrameDuration);
+ QueueAbortedRead();
scherkus (not reviewing) 2012/12/05 00:03:46 ditto here -- but I'm also not sure what we're sup
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 Aborted reads when the ChunkDemuxer can't satisfy
Pause();
Flush();
- Preroll(kFrameDuration * 6);
- ExpectCurrentTimestamp(kFrameDuration * 6);
+ QueuePrerollFrames(kFrameDuration * 6);
+ Preroll(kFrameDuration * 6, PIPELINE_OK);
+ EXPECT_EQ(kFrameDuration * 6, GetCurrentTimestamp());
Shutdown();
}
@@ -672,8 +626,8 @@ TEST_F(VideoRendererBaseTest, AbortPendingRead_Flush) {
Initialize();
Play();
- // Render a frame to trigger a Read().
- RenderFrame(kFrameDuration);
+ // Advance time a bit to trigger a Read().
+ SetTime(kFrameDuration);
scherkus (not reviewing) 2012/12/05 00:03:46 ditto
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 I think this one is ok assuming it executes the !r
Pause();
Flush();
@@ -684,9 +638,9 @@ TEST_F(VideoRendererBaseTest, AbortPendingRead_Preroll) {
Initialize();
Pause();
Flush();
- StartPrerolling(kFrameDuration * 6, PIPELINE_OK);
- AbortRead();
- VerifyNotPrerolling();
+
+ QueueAbortedRead();
+ Preroll(kFrameDuration * 6, PIPELINE_OK);
scherkus (not reviewing) 2012/12/05 00:03:46 this one makes sense -- since we don't call QueueP
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 As I mentioned above, the abort tests have more to
Shutdown();
}
@@ -696,6 +650,8 @@ TEST_F(VideoRendererBaseTest, VideoDecoder_InitFailure) {
EXPECT_CALL(*decoder_, Initialize(_, _, _))
.WillOnce(RunCallback<1>(PIPELINE_ERROR_DECODE));
InitializeRenderer(PIPELINE_ERROR_DECODE);
+
+ Stop();
acolwell GONE FROM CHROMIUM 2012/12/05 18:15:25 Why is stop needed? The initialization failed.
scherkus (not reviewing) 2012/12/05 21:52:03 VRB DCHECKs in the dtor that the state is uninitia
acolwell GONE FROM CHROMIUM 2012/12/05 23:00:54 ok. TODO for removal w/ VRB changes?
}
} // namespace media
« media/base/mock_callback.h ('K') | « media/filters/ffmpeg_demuxer_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698