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

Unified Diff: media/filters/video_renderer_impl_unittest.cc

Issue 237353007: Refactor VideoRendererImpl to use VideoFrameScheduler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: pretty much done Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..f9e115d182843fd5074375479343dcb2434988bc 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,35 @@ 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());
+ bool pending_read() { return !read_cb_.is_null(); }
+ base::TimeDelta time() { return time_; }
+ void set_time(base::TimeDelta time) { time_ = time; }
+ base::TimeDelta max_time() { return max_time_; }
+ int decoded_frames() { return decoded_frames_; }
+ int dropped_frames() { return dropped_frames_; }
+ bool ended_cb_run() { return ended_cb_run_; }
xhwang 2014/04/24 18:48:44 nit: make getters const?
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+
+ base::TimeDelta duration() {
+ // Arbitrary value. Has to be larger to cover any timestamp used in tests.
acolwell GONE FROM CHROMIUM 2014/04/24 16:43:59 nit: s/larger/large/?
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+ return base::TimeDelta::FromMilliseconds(1000);
}
protected:
- // Fixture members.
+ base::MessageLoop message_loop_;
+
scoped_ptr<VideoRendererImpl> renderer_;
MockVideoDecoder* decoder_; // Owned by |renderer_|.
+ TestVideoFrameScheduler* scheduler_; // Owned by |renderer_|.
+ base::SimpleTestTickClock* tick_clock_; // Owned by |renderer_|.
xhwang 2014/04/24 18:48:44 nit: if you align the comments, why not also align
scherkus (not reviewing) 2014/04/25 02:04:47 Done. (I think clang-format did this)
NiceMock<MockDemuxerStream> demuxer_stream_;
- MockStatisticsCB statistics_cb_object_;
-
- // 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_;
private:
- base::TimeDelta GetTime() {
- base::AutoLock l(lock_);
- return time_;
- }
-
- base::TimeDelta GetDuration() {
- return base::TimeDelta::FromMilliseconds(kVideoDurationInMs);
- }
-
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 +269,28 @@ 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;
+ }
// 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 +308,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 +331,246 @@ 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(1u, scheduler_->scheduled_frames().size());
+ EXPECT_EQ(base::TimeDelta(),
+ scheduler_->scheduled_frames().front().frame->timestamp());
+ EXPECT_EQ(base::TimeTicks(),
xhwang 2014/04/24 18:48:44 Should base::TimeTicks() be tick_clock_->NowTicks(
scherkus (not reviewing) 2014/04/25 02:04:47 Replaced with string format.
+ scheduler_->scheduled_frames().front().wall_ticks);
+
+ 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(4u, scheduler_->scheduled_frames().size());
+ EXPECT_EQ(base::TimeDelta(),
+ scheduler_->scheduled_frames()[0].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks);
acolwell GONE FROM CHROMIUM 2014/04/24 16:43:59 String format verification for these too? Either t
xhwang 2014/04/24 18:48:44 ditto about tick_clock_->NowTicks(). Agreed with a
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(10),
+ scheduler_->scheduled_frames()[1].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(10000),
+ scheduler_->scheduled_frames()[1].wall_ticks);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
+ scheduler_->scheduled_frames()[2].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(20000),
+ scheduler_->scheduled_frames()[2].wall_ticks);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(30),
+ scheduler_->scheduled_frames()[3].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(30000),
+ scheduler_->scheduled_frames()[3].wall_ticks);
+
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(0u, scheduler_->scheduled_frames().size());
xhwang 2014/04/24 18:48:44 Also check that "RESET" frames are pushed back to
scherkus (not reviewing) 2014/04/25 02:04:47 Isn't needed due to change in Reset() behaviour
+
+ Shutdown();
+}
+
+TEST_F(VideoRendererImplTest, PauseWaitsForResetFrames) {
+ Initialize();
+ QueueFrames("0 10 20 30");
+ Preroll(0, PIPELINE_OK);
+ Play();
+
+ scheduler_->set_should_reset(false);
acolwell GONE FROM CHROMIUM 2014/04/24 16:43:59 This is for simulating the proxy VFS case right? A
scherkus (not reviewing) 2014/04/25 02:04:47 Removed this test case due to change in Reset() be
+
+ bool pause_cb_run = false;
+ renderer_->Pause(base::Bind(&AssignValue, &pause_cb_run, true));
+ EXPECT_FALSE(pause_cb_run);
+
+ scheduler_->set_should_reset(true);
+ scheduler_->Reset();
xhwang 2014/04/24 18:48:44 See comments above about calling scheduler_->Reset
scherkus (not reviewing) 2014/04/25 02:04:47 Ditto
+ EXPECT_TRUE(pause_cb_run);
+
+ Shutdown();
+}
+
+TEST_F(VideoRendererImplTest, SetPlaybackRateReschedulesFrames) {
+ Initialize();
+ QueueFrames("0 10 20 30");
+ Preroll(0, PIPELINE_OK);
+ Play();
+
+ renderer_->SetPlaybackRate(2.0);
+
xhwang 2014/04/24 18:48:44 hmm, Reset() and SetPlaybackRate() all finishes sy
scherkus (not reviewing) 2014/04/25 02:04:47 actually this test started failing once I made Res
+ // Wall times should be cut in half.
+ EXPECT_EQ(4u, scheduler_->scheduled_frames().size());
acolwell GONE FROM CHROMIUM 2014/04/24 16:43:59 ditto. more concise expectations would be nice.
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+ EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks);
xhwang 2014/04/24 18:48:44 So even the first frame is rescheduled because Res
scherkus (not reviewing) 2014/04/25 02:04:47 had to change this stuff
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(10),
+ scheduler_->scheduled_frames()[1].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(5000),
+ scheduler_->scheduled_frames()[1].wall_ticks);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
+ scheduler_->scheduled_frames()[2].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(10000),
+ scheduler_->scheduled_frames()[2].wall_ticks);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(30),
+ scheduler_->scheduled_frames()[3].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(15000),
+ scheduler_->scheduled_frames()[3].wall_ticks);
+
+ 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.
+ EXPECT_EQ(4u, scheduler_->scheduled_frames().size());
+ EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[0].wall_ticks);
xhwang 2014/04/24 18:48:44 So this is from the ScheduleFirstFrameForImmediate
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(10),
+ scheduler_->scheduled_frames()[1].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(-10000),
+ scheduler_->scheduled_frames()[1].wall_ticks);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
+ scheduler_->scheduled_frames()[2].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks(), scheduler_->scheduled_frames()[2].wall_ticks);
xhwang 2014/04/24 18:48:44 This make it harder to read, I'd rather see base::
scherkus (not reviewing) 2014/04/25 02:04:47 Replaced with string format.
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(30),
+ scheduler_->scheduled_frames()[3].frame->timestamp());
+ EXPECT_EQ(base::TimeTicks::FromInternalValue(10000),
+ scheduler_->scheduled_frames()[3].wall_ticks);
+
+ Shutdown();
+}
+
+TEST_F(VideoRendererImplTest, EndedWaitsForLastFrame) {
+ Initialize();
+ QueueFrames("0 10 20 30 eos");
+ Preroll(0, PIPELINE_OK);
+ Play();
+
+ // Display up to last frame.
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(20000));
xhwang 2014/04/24 18:48:44 Write a helper function DisplayFrames(ms) so that
scherkus (not reviewing) 2014/04/25 02:04:47 Done.
+ message_loop_.RunUntilIdle();
+ EXPECT_FALSE(ended_cb_run());
+
+ // Display last frame.
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000));
+ 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.
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000));
+ message_loop_.RunUntilIdle();
+ EXPECT_FALSE(ended_cb_run());
+
+ // Deliver end of stream.
+ QueueFrames("eos");
+ 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();
- // Queue the end of stream frame and wait for the last frame to be rendered.
+ // 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");
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(kVideoDurationInMs)));
- AdvanceTimeInMs(kVideoDurationInMs);
- WaitForEnded();
+
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_EQ(1u, scheduler_->scheduled_frames().size());
+ EXPECT_EQ(duration(),
+ scheduler_->scheduled_frames().front().frame->timestamp());
+
+ 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());
+
+ scheduler_->DisplayFrames(base::TimeTicks());
+
+ 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());
+
+ scheduler_->DropFrames(base::TimeTicks());
+
+ EXPECT_EQ(1, decoded_frames());
+ EXPECT_EQ(1, dropped_frames());
Shutdown();
}
@@ -421,13 +578,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();
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000));
+ EXPECT_TRUE(pending_read());
+
QueueFrames("error");
- EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
- AdvanceTimeInMs(10);
+ SatisfyPendingRead();
WaitForError(PIPELINE_ERROR_DECODE);
Shutdown();
}
@@ -442,54 +600,51 @@ 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(base::TimeDelta::FromMilliseconds(60),
+ scheduler_->scheduled_frames().front().frame->timestamp());
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(base::TimeDelta::FromMilliseconds(50),
+ scheduler_->scheduled_frames().front().frame->timestamp());
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(base::TimeDelta::FromMilliseconds(60),
+ scheduler_->scheduled_frames().front().frame->timestamp());
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();
+ scheduler_->DisplayFrames(base::TimeTicks());
+ 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.
+ scheduler_->DisplayFrames(base::TimeTicks::FromInternalValue(30000));
+ EXPECT_TRUE(pending_read());
// Simulate a Pause/Preroll/Play rebuffer sequence.
Pause();
@@ -501,12 +656,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(1u, scheduler_->scheduled_frames().size());
Play();
@@ -516,27 +670,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(1u, scheduler_->scheduled_frames().size());
+
Play();
Shutdown();
@@ -546,14 +694,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();
+ scheduler_->DisplayFrames(base::TimeTicks());
+ EXPECT_TRUE(pending_read());
WaitableMessageLoopEvent event;
renderer_->Stop(event.GetClosure());
@@ -563,21 +708,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();
+ scheduler_->DisplayFrames(base::TimeTicks());
+ 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 +726,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();
+ scheduler_->DisplayFrames(base::TimeTicks());
+ EXPECT_TRUE(pending_read());
Pause();
Flush();
@@ -602,14 +740,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);

Powered by Google App Engine
This is Rietveld 408576698