Index: media/filters/video_renderer_impl_unittest.cc |
diff --git a/media/filters/video_renderer_impl_unittest.cc b/media/filters/video_renderer_impl_unittest.cc |
index 84ccc9ed29a9fd2f5890aa9c7a842cd395416a4a..14d81b80a0dadcc683f1c3c9191d75364365b188 100644 |
--- a/media/filters/video_renderer_impl_unittest.cc |
+++ b/media/filters/video_renderer_impl_unittest.cc |
@@ -2,62 +2,51 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include <utility> |
- |
#include "base/bind.h" |
-#include "base/callback.h" |
-#include "base/callback_helpers.h" |
#include "base/debug/stack_trace.h" |
#include "base/message_loop/message_loop.h" |
-#include "base/stl_util.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_split.h" |
#include "base/strings/stringprintf.h" |
-#include "base/synchronization/lock.h" |
-#include "base/timer/timer.h" |
-#include "media/base/data_buffer.h" |
+#include "base/test/simple_test_tick_clock.h" |
#include "media/base/gmock_callback_support.h" |
-#include "media/base/limits.h" |
#include "media/base/mock_filters.h" |
#include "media/base/test_helpers.h" |
-#include "media/base/video_frame.h" |
+#include "media/filters/test_video_frame_scheduler.h" |
#include "media/filters/video_renderer_impl.h" |
#include "testing/gtest/include/gtest/gtest.h" |
using ::testing::_; |
using ::testing::AnyNumber; |
-using ::testing::InSequence; |
using ::testing::Invoke; |
using ::testing::NiceMock; |
-using ::testing::NotNull; |
-using ::testing::Return; |
-using ::testing::StrictMock; |
namespace media { |
-MATCHER_P(HasTimestamp, ms, "") { |
- *result_listener << "has timestamp " << arg->timestamp().InMilliseconds(); |
- return arg->timestamp().InMilliseconds() == ms; |
+static void AssignValue(bool* b, bool value) { |
+ *b = value; |
} |
-// Arbitrary value. Has to be larger to cover any timestamp value used in tests. |
-static const int kVideoDurationInMs = 1000; |
- |
class VideoRendererImplTest : public ::testing::Test { |
public: |
VideoRendererImplTest() |
: decoder_(new MockVideoDecoder()), |
- demuxer_stream_(DemuxerStream::VIDEO) { |
+ scheduler_(new TestVideoFrameScheduler()), |
+ tick_clock_(new base::SimpleTestTickClock()), |
+ demuxer_stream_(DemuxerStream::VIDEO), |
+ max_time_(kNoTimestamp()), |
+ decoded_frames_(0), |
+ dropped_frames_(0), |
+ ended_cb_run_(false) { |
ScopedVector<VideoDecoder> decoders; |
decoders.push_back(decoder_); |
renderer_.reset( |
new VideoRendererImpl(message_loop_.message_loop_proxy(), |
+ scoped_ptr<VideoFrameScheduler>(scheduler_), |
decoders.Pass(), |
- media::SetDecryptorReadyCB(), |
- base::Bind(&StrictMock<MockDisplayCB>::Display, |
- base::Unretained(&mock_display_cb_)), |
- true)); |
+ media::SetDecryptorReadyCB())); |
+ renderer_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_)); |
demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal()); |
@@ -67,17 +56,10 @@ class VideoRendererImplTest : public ::testing::Test { |
DecoderBuffer::CreateEOSBuffer())); |
EXPECT_CALL(*decoder_, Stop()) |
.WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested)); |
- EXPECT_CALL(statistics_cb_object_, OnStatistics(_)) |
- .Times(AnyNumber()); |
- EXPECT_CALL(*this, OnTimeUpdate(_)) |
- .Times(AnyNumber()); |
} |
virtual ~VideoRendererImplTest() {} |
- // Callbacks passed into Initialize(). |
- MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta)); |
- |
void Initialize() { |
// Monitor decodes from the decoder. |
EXPECT_CALL(*decoder_, Decode(_, _)) |
@@ -86,8 +68,6 @@ class VideoRendererImplTest : public ::testing::Test { |
EXPECT_CALL(*decoder_, Reset(_)) |
.WillRepeatedly(Invoke(this, &VideoRendererImplTest::FlushRequested)); |
- InSequence s; |
- |
EXPECT_CALL(*decoder_, Initialize(_, _)) |
.WillOnce(RunCallback<1>(PIPELINE_OK)); |
@@ -109,15 +89,14 @@ class VideoRendererImplTest : public ::testing::Test { |
renderer_->Initialize( |
&demuxer_stream_, |
status_cb, |
- base::Bind(&MockStatisticsCB::OnStatistics, |
- base::Unretained(&statistics_cb_object_)), |
- base::Bind(&VideoRendererImplTest::OnTimeUpdate, |
+ base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, |
+ base::Unretained(this)), |
+ base::Bind(&VideoRendererImplTest::OnMaxTimeUpdate, |
base::Unretained(this)), |
- ended_event_.GetClosure(), |
+ base::Bind(&AssignValue, &ended_cb_run_, true), |
error_event_.GetPipelineStatusCB(), |
- base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), |
- base::Bind(&VideoRendererImplTest::GetDuration, |
- base::Unretained(this))); |
+ base::Bind(&VideoRendererImplTest::time, base::Unretained(this)), |
+ base::Bind(&VideoRendererImplTest::duration, base::Unretained(this))); |
} |
void Play() { |
@@ -221,26 +200,6 @@ class VideoRendererImplTest : public ::testing::Test { |
error_event_.RunAndWaitForStatus(expected); |
} |
- void WaitForEnded() { |
- SCOPED_TRACE("WaitForEnded()"); |
- ended_event_.RunAndWait(); |
- } |
- |
- void WaitForPendingRead() { |
- SCOPED_TRACE("WaitForPendingRead()"); |
- if (!read_cb_.is_null()) |
- return; |
- |
- DCHECK(wait_for_pending_read_cb_.is_null()); |
- |
- WaitableMessageLoopEvent event; |
- wait_for_pending_read_cb_ = event.GetClosure(); |
- event.RunAndWait(); |
- |
- DCHECK(!read_cb_.is_null()); |
- DCHECK(wait_for_pending_read_cb_.is_null()); |
- } |
- |
void SatisfyPendingRead() { |
CHECK(!read_cb_.is_null()); |
CHECK(!decode_results_.empty()); |
@@ -255,47 +214,74 @@ class VideoRendererImplTest : public ::testing::Test { |
message_loop_.PostTask(FROM_HERE, closure); |
} |
- void AdvanceTimeInMs(int time_ms) { |
- DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
- base::AutoLock l(lock_); |
- time_ += base::TimeDelta::FromMilliseconds(time_ms); |
- DCHECK_LE(time_.InMicroseconds(), GetDuration().InMicroseconds()); |
+ void DisplayFramesUpTo(int ms) { |
+ scheduler_->DisplayFramesUpTo( |
+ base::TimeTicks::FromInternalValue(ms * 1000)); |
} |
- protected: |
- // Fixture members. |
- scoped_ptr<VideoRendererImpl> renderer_; |
- MockVideoDecoder* decoder_; // Owned by |renderer_|. |
- NiceMock<MockDemuxerStream> demuxer_stream_; |
- MockStatisticsCB statistics_cb_object_; |
+ void DropFramesUpTo(int ms) { |
+ scheduler_->DropFramesUpTo( |
+ base::TimeTicks::FromInternalValue(ms * 1000)); |
+ } |
- // Use StrictMock<T> to catch missing/extra display callbacks. |
- class MockDisplayCB { |
- public: |
- MOCK_METHOD1(Display, void(const scoped_refptr<VideoFrame>&)); |
- }; |
- StrictMock<MockDisplayCB> mock_display_cb_; |
+ // Returns a string representation of all scheduled frames' timestamps. |
+ // Timestamps are in milliseconds. |
+ // |
+ // Example: "0 10 20" |
+ std::string ScheduledFrameTimestamps() { |
+ std::string str; |
+ for (size_t i = 0; i < scheduler_->scheduled_frames().size(); ++i) { |
+ base::TimeDelta timestamp = |
+ scheduler_->scheduled_frames()[i].frame->timestamp(); |
+ |
+ if (i > 0) |
+ str += " "; |
+ str += base::Int64ToString(timestamp.InMilliseconds()); |
+ } |
+ return str; |
+ } |
- private: |
- base::TimeDelta GetTime() { |
- base::AutoLock l(lock_); |
- return time_; |
+ // Returns a string representation of all scheduled frames' wall ticks. Ticks |
+ // are represented using their internal value. |
+ // |
+ // Example: "0 10000 20000" |
+ std::string ScheduledFrameWallTicks() { |
+ std::string str; |
+ for (size_t i = 0; i < scheduler_->scheduled_frames().size(); ++i) { |
+ base::TimeTicks wall_ticks = scheduler_->scheduled_frames()[i].wall_ticks; |
+ |
+ if (i > 0) |
+ str += " "; |
+ str += base::Int64ToString(wall_ticks.ToInternalValue()); |
+ } |
+ return str; |
} |
- base::TimeDelta GetDuration() { |
- return base::TimeDelta::FromMilliseconds(kVideoDurationInMs); |
+ bool pending_read() const { return !read_cb_.is_null(); } |
+ base::TimeDelta time() const { return time_; } |
+ void set_time(base::TimeDelta time) { time_ = time; } |
+ base::TimeDelta max_time() const { return max_time_; } |
+ int decoded_frames() const { return decoded_frames_; } |
+ int dropped_frames() const { return dropped_frames_; } |
+ bool ended_cb_run() const { return ended_cb_run_; } |
+ |
+ base::TimeDelta duration() const { |
+ // Arbitrary value. Has to be large to cover any timestamp used in tests. |
+ return base::TimeDelta::FromMilliseconds(1000); |
} |
+ protected: |
+ base::MessageLoop message_loop_; |
+ scoped_ptr<VideoRendererImpl> renderer_; |
+ MockVideoDecoder* decoder_; // Owned by |renderer_|. |
+ |
+ private: |
void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer, |
const VideoDecoder::DecodeCB& read_cb) { |
DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
CHECK(read_cb_.is_null()); |
read_cb_ = read_cb; |
- // Wake up WaitForPendingRead() if needed. |
- if (!wait_for_pending_read_cb_.is_null()) |
- base::ResetAndReturn(&wait_for_pending_read_cb_).Run(); |
- |
if (decode_results_.empty()) |
return; |
@@ -322,25 +308,32 @@ class VideoRendererImplTest : public ::testing::Test { |
} |
} |
- base::MessageLoop message_loop_; |
+ void OnMaxTimeUpdate(base::TimeDelta max_time) { max_time_ = max_time; } |
- // Used to protect |time_|. |
- base::Lock lock_; |
- base::TimeDelta time_; |
+ void OnStatisticsUpdate(const PipelineStatistics& stats) { |
+ decoded_frames_ = stats.video_frames_decoded; |
+ dropped_frames_ = stats.video_frames_dropped; |
+ } |
+ |
+ TestVideoFrameScheduler* scheduler_; // Owned by |renderer_|. |
+ base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|. |
+ NiceMock<MockDemuxerStream> demuxer_stream_; |
// Used for satisfying reads. |
VideoDecoder::DecodeCB read_cb_; |
base::TimeDelta next_frame_timestamp_; |
WaitableMessageLoopEvent error_event_; |
- WaitableMessageLoopEvent ended_event_; |
- |
- // Run during FrameRequested() to unblock WaitForPendingRead(). |
- base::Closure wait_for_pending_read_cb_; |
std::deque<std::pair< |
VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_; |
+ base::TimeDelta time_; |
+ base::TimeDelta max_time_; |
+ int decoded_frames_; |
+ int dropped_frames_; |
+ bool ended_cb_run_; |
+ |
DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); |
}; |
@@ -358,14 +351,6 @@ TEST_F(VideoRendererImplTest, Initialize) { |
Shutdown(); |
} |
-TEST_F(VideoRendererImplTest, InitializeAndPreroll) { |
- Initialize(); |
- QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
- Preroll(0, PIPELINE_OK); |
- Shutdown(); |
-} |
- |
static void ExpectNotCalled(PipelineStatus) { |
base::debug::StackTrace stack; |
ADD_FAILURE() << "Expected callback not to be called\n" << stack.ToString(); |
@@ -389,31 +374,192 @@ TEST_F(VideoRendererImplTest, StopWhileFlushing) { |
// ~VideoRendererImpl() will CHECK() if we left anything initialized. |
} |
-TEST_F(VideoRendererImplTest, Play) { |
+TEST_F(VideoRendererImplTest, PrerollSchedulesFirstFrame) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ |
+ EXPECT_EQ("0", ScheduledFrameTimestamps()); |
+ EXPECT_EQ("0", ScheduledFrameWallTicks()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, PlaySchedulesAllFrames) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
+ |
+ EXPECT_EQ("0 10 20 30", ScheduledFrameTimestamps()); |
+ EXPECT_EQ("0 10000 20000 30000", ScheduledFrameWallTicks()); |
+ |
Shutdown(); |
} |
-TEST_F(VideoRendererImplTest, EndOfStream_ClipDuration) { |
+TEST_F(VideoRendererImplTest, PauseResetsScheduledFrames) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
+ Pause(); |
- // Next frame has timestamp way past duration. Its timestamp will be adjusted |
- // to match the duration of the video. |
- QueueFrames(base::IntToString(kVideoDurationInMs + 1000)); |
+ EXPECT_EQ("", ScheduledFrameTimestamps()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, SetPlaybackRateReschedulesFrames) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ renderer_->SetPlaybackRate(2.0); |
+ |
+ // Wall times should be cut in half. |
+ EXPECT_EQ("0 10 20 30", ScheduledFrameTimestamps()); |
+ EXPECT_EQ("0 5000 10000 15000", ScheduledFrameWallTicks()); |
+ |
+ renderer_->SetPlaybackRate(0.5); |
+ |
+ // Wall times should be doubled. |
+ EXPECT_EQ("0 10 20 30", ScheduledFrameTimestamps()); |
+ EXPECT_EQ("0 20000 40000 60000", ScheduledFrameWallTicks()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, MediaTimeUsedToScheduleFrames) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ |
+ // Introduce an offset in the media time before playing. |
+ set_time(base::TimeDelta::FromMilliseconds(20)); |
+ |
+ Play(); |
+ |
+ // All newly scheduled frames should respect the media time. |
+ // The first frame is present due to prerolling. |
+ EXPECT_EQ("0 10 20 30", ScheduledFrameTimestamps()); |
+ EXPECT_EQ("0 -10000 0 10000", ScheduledFrameWallTicks()); |
+ |
+ Shutdown(); |
+} |
- // Queue the end of stream frame and wait for the last frame to be rendered. |
+TEST_F(VideoRendererImplTest, EndedWaitsForLastFrame) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30 eos"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ // Display up to last frame. |
+ DisplayFramesUpTo(20); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_FALSE(ended_cb_run()); |
+ |
+ // Display last frame. |
+ DisplayFramesUpTo(30); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_TRUE(ended_cb_run()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, EndedWaitsForEndOfStream) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ // Display last frame. |
+ DisplayFramesUpTo(30); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_FALSE(ended_cb_run()); |
+ |
+ // Deliver end of stream. |
QueueFrames("eos"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(kVideoDurationInMs))); |
- AdvanceTimeInMs(kVideoDurationInMs); |
- WaitForEnded(); |
+ SatisfyPendingRead(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_TRUE(ended_cb_run()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, AdjustTimestampsPastDuration) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ // Last frame has timestamp way past duration. Its timestamp will be adjusted |
+ // to match the duration of the video. |
+ QueueFrames(base::IntToString((duration() * 10).InMilliseconds())); |
+ QueueFrames("eos"); |
+ |
+ DisplayFramesUpTo(30); |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ("1000", ScheduledFrameTimestamps()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, IncomingFramesUpdateMaxTime) { |
+ EXPECT_EQ(kNoTimestamp(), max_time()); |
+ |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ |
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(30), max_time()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, EndOfStreamSetsMaxTimeToDuration) { |
+ EXPECT_EQ(kNoTimestamp(), max_time()); |
+ |
+ Initialize(); |
+ QueueFrames("0 10 20 eos"); |
+ Preroll(0, PIPELINE_OK); |
+ |
+ EXPECT_EQ(duration(), max_time()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, DisplayedFramesIncrementStatistics) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ EXPECT_EQ(0, decoded_frames()); |
+ EXPECT_EQ(0, dropped_frames()); |
+ |
+ DisplayFramesUpTo(0); |
+ |
+ EXPECT_EQ(1, decoded_frames()); |
+ EXPECT_EQ(0, dropped_frames()); |
+ |
+ Shutdown(); |
+} |
+ |
+TEST_F(VideoRendererImplTest, DroppedFramesIncrementStatistics) { |
+ Initialize(); |
+ QueueFrames("0 10 20 30"); |
+ Preroll(0, PIPELINE_OK); |
+ Play(); |
+ |
+ EXPECT_EQ(0, decoded_frames()); |
+ EXPECT_EQ(0, dropped_frames()); |
+ |
+ DropFramesUpTo(0); |
+ |
+ EXPECT_EQ(1, decoded_frames()); |
+ EXPECT_EQ(1, dropped_frames()); |
Shutdown(); |
} |
@@ -421,13 +567,14 @@ TEST_F(VideoRendererImplTest, EndOfStream_ClipDuration) { |
TEST_F(VideoRendererImplTest, DecodeError_Playing) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
+ DisplayFramesUpTo(3); |
+ EXPECT_TRUE(pending_read()); |
+ |
QueueFrames("error"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); |
- AdvanceTimeInMs(10); |
+ SatisfyPendingRead(); |
WaitForError(PIPELINE_ERROR_DECODE); |
Shutdown(); |
} |
@@ -442,54 +589,48 @@ TEST_F(VideoRendererImplTest, DecodeError_DuringPreroll) { |
TEST_F(VideoRendererImplTest, Preroll_Exact) { |
Initialize(); |
QueueFrames("50 60 70 80 90"); |
- |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); |
Preroll(60, PIPELINE_OK); |
+ EXPECT_EQ("60", ScheduledFrameTimestamps()); |
Shutdown(); |
} |
TEST_F(VideoRendererImplTest, Preroll_RightBefore) { |
Initialize(); |
QueueFrames("50 60 70 80 90"); |
- |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(50))); |
Preroll(59, PIPELINE_OK); |
+ EXPECT_EQ("50", ScheduledFrameTimestamps()); |
Shutdown(); |
} |
TEST_F(VideoRendererImplTest, Preroll_RightAfter) { |
Initialize(); |
QueueFrames("50 60 70 80 90"); |
- |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); |
Preroll(61, PIPELINE_OK); |
+ EXPECT_EQ("60", ScheduledFrameTimestamps()); |
Shutdown(); |
} |
TEST_F(VideoRendererImplTest, PlayAfterPreroll) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
- // Advance time past prerolled time to trigger a Read(). |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); |
- AdvanceTimeInMs(10); |
- WaitForPendingRead(); |
+ DisplayFramesUpTo(0); |
+ EXPECT_TRUE(pending_read()); |
+ |
Shutdown(); |
} |
TEST_F(VideoRendererImplTest, Rebuffer) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
- // Advance time past prerolled time drain the ready frame queue. |
- AdvanceTimeInMs(50); |
- WaitForPendingRead(); |
+ // Display all frames to empty frame buffer. |
+ DisplayFramesUpTo(30); |
+ EXPECT_TRUE(pending_read()); |
// Simulate a Pause/Preroll/Play rebuffer sequence. |
Pause(); |
@@ -501,12 +642,11 @@ TEST_F(VideoRendererImplTest, Rebuffer) { |
// Queue enough frames to satisfy preroll. |
QueueFrames("40 50 60 70"); |
SatisfyPendingRead(); |
+ event.RunAndWaitForStatus(PIPELINE_OK); |
// TODO(scherkus): We shouldn't display the next ready frame in a rebuffer |
// situation, see http://crbug.com/365516 |
- EXPECT_CALL(mock_display_cb_, Display(_)); |
- |
- event.RunAndWaitForStatus(PIPELINE_OK); |
+ EXPECT_EQ("40", ScheduledFrameTimestamps()); |
Play(); |
@@ -516,27 +656,21 @@ TEST_F(VideoRendererImplTest, Rebuffer) { |
TEST_F(VideoRendererImplTest, Rebuffer_AlreadyHaveEnoughFrames) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
- |
- // Queue an extra frame so that we'll have enough frames to satisfy |
- // preroll even after the first frame is painted. |
- QueueFrames("40"); |
Play(); |
// Simulate a Pause/Preroll/Play rebuffer sequence. |
Pause(); |
- // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer |
- // situation, see http://crbug.com/365516 |
- EXPECT_CALL(mock_display_cb_, Display(_)); |
- |
WaitableMessageLoopEvent event; |
renderer_->Preroll(kNoTimestamp(), |
event.GetPipelineStatusCB()); |
- |
event.RunAndWaitForStatus(PIPELINE_OK); |
+ // TODO(scherkus): We shouldn't display the next ready frame in a rebuffer |
+ // situation, see http://crbug.com/365516 |
+ EXPECT_EQ("0", ScheduledFrameTimestamps()); |
+ |
Play(); |
Shutdown(); |
@@ -546,14 +680,11 @@ TEST_F(VideoRendererImplTest, Rebuffer_AlreadyHaveEnoughFrames) { |
TEST_F(VideoRendererImplTest, StopDuringOutstandingRead) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
- // Advance time a bit to trigger a Read(). |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); |
- AdvanceTimeInMs(10); |
- WaitForPendingRead(); |
+ DisplayFramesUpTo(0); |
+ EXPECT_TRUE(pending_read()); |
WaitableMessageLoopEvent event; |
renderer_->Stop(event.GetClosure()); |
@@ -563,21 +694,17 @@ TEST_F(VideoRendererImplTest, StopDuringOutstandingRead) { |
TEST_F(VideoRendererImplTest, AbortPendingRead_Playing) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
- // Advance time a bit to trigger a Read(). |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); |
- AdvanceTimeInMs(10); |
- WaitForPendingRead(); |
+ DisplayFramesUpTo(0); |
+ EXPECT_TRUE(pending_read()); |
QueueFrames("abort"); |
SatisfyPendingRead(); |
Pause(); |
Flush(); |
QueueFrames("60 70 80 90"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(60))); |
Preroll(60, PIPELINE_OK); |
Shutdown(); |
} |
@@ -585,14 +712,11 @@ TEST_F(VideoRendererImplTest, AbortPendingRead_Playing) { |
TEST_F(VideoRendererImplTest, AbortPendingRead_Flush) { |
Initialize(); |
QueueFrames("0 10 20 30"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Play(); |
- // Advance time a bit to trigger a Read(). |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10))); |
- AdvanceTimeInMs(10); |
- WaitForPendingRead(); |
+ DisplayFramesUpTo(0); |
+ EXPECT_TRUE(pending_read()); |
Pause(); |
Flush(); |
@@ -602,14 +726,11 @@ TEST_F(VideoRendererImplTest, AbortPendingRead_Flush) { |
TEST_F(VideoRendererImplTest, AbortPendingRead_Preroll) { |
Initialize(); |
QueueFrames("0 10 abort"); |
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0))); |
Preroll(0, PIPELINE_OK); |
Shutdown(); |
} |
TEST_F(VideoRendererImplTest, VideoDecoder_InitFailure) { |
- InSequence s; |
- |
EXPECT_CALL(*decoder_, Initialize(_, _)) |
.WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)); |
InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED); |