| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..691815d2e053fe822afd8e16adb087231885f829
|
| --- /dev/null
|
| +++ b/media/filters/video_renderer_base_unittest.cc
|
| @@ -0,0 +1,215 @@
|
| +// Copyright (c) 2009 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 "base/stl_util-inl.h"
|
| +#include "media/base/data_buffer.h"
|
| +#include "media/base/mock_filter_host.h"
|
| +#include "media/base/mock_filters.h"
|
| +#include "media/base/video_frame_impl.h"
|
| +#include "media/filters/video_renderer_base.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using ::testing::_;
|
| +using ::testing::AnyNumber;
|
| +using ::testing::InSequence;
|
| +using ::testing::Invoke;
|
| +using ::testing::NotNull;
|
| +using ::testing::Return;
|
| +using ::testing::StrictMock;
|
| +
|
| +namespace media {
|
| +
|
| +// Mocked subclass of VideoRendererBase for testing purposes.
|
| +class MockVideoRendererBase : public VideoRendererBase {
|
| + public:
|
| + MockVideoRendererBase() {}
|
| + virtual ~MockVideoRendererBase() {}
|
| +
|
| + // VideoRendererBase implementation.
|
| + MOCK_METHOD1(OnInitialize, bool (VideoDecoder* decoder));
|
| + MOCK_METHOD0(OnStop, void());
|
| + MOCK_METHOD0(OnFrameAvailable, void());
|
| +
|
| + // Used for verifying check points during tests.
|
| + MOCK_METHOD1(CheckPoint, void(int id));
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(MockVideoRendererBase);
|
| +};
|
| +
|
| +class VideoRendererBaseTest : public ::testing::Test {
|
| + public:
|
| + VideoRendererBaseTest()
|
| + : renderer_(new MockVideoRendererBase()),
|
| + decoder_(new MockVideoDecoder(mime_type::kUncompressedVideo, kWidth,
|
| + kHeight)) {
|
| + renderer_->set_host(&host_);
|
| +
|
| + // Queue all reads from the decoder.
|
| + EXPECT_CALL(*decoder_, Read(NotNull()))
|
| + .WillRepeatedly(Invoke(this, &VideoRendererBaseTest::EnqueueCallback));
|
| + }
|
| +
|
| + virtual ~VideoRendererBaseTest() {
|
| + STLDeleteElements(&read_queue_);
|
| +
|
| + // Expect a call into the subclass.
|
| + EXPECT_CALL(*renderer_, OnStop());
|
| + renderer_->Stop();
|
| + }
|
| +
|
| + protected:
|
| + static const size_t kWidth;
|
| + static const size_t kHeight;
|
| +
|
| + // Fixture members.
|
| + scoped_refptr<MockVideoRendererBase> renderer_;
|
| + scoped_refptr<MockVideoDecoder> decoder_;
|
| + StrictMock<MockFilterHost> host_;
|
| + StrictMock<MockFilterCallback> callback_;
|
| +
|
| + // Receives asynchronous read requests sent to |decoder_|.
|
| + std::deque<Callback1<VideoFrame*>::Type*> read_queue_;
|
| +
|
| + private:
|
| + void EnqueueCallback(Callback1<VideoFrame*>::Type* callback) {
|
| + read_queue_.push_back(callback);
|
| + }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(VideoRendererBaseTest);
|
| +};
|
| +
|
| +const size_t VideoRendererBaseTest::kWidth = 16u;
|
| +const size_t VideoRendererBaseTest::kHeight = 16u;
|
| +
|
| +// Test initialization where the decoder's media format is malformed.
|
| +TEST_F(VideoRendererBaseTest, Initialize_BadMediaFormat) {
|
| + InSequence s;
|
| +
|
| + // Don't set a media format.
|
| + scoped_refptr<MockVideoDecoder> bad_decoder = new MockVideoDecoder();
|
| +
|
| + // We expect to receive an error.
|
| + EXPECT_CALL(host_, Error(PIPELINE_ERROR_INITIALIZATION_FAILED));
|
| +
|
| + // We expect our callback to be executed.
|
| + EXPECT_CALL(callback_, OnFilterCallback());
|
| + EXPECT_CALL(callback_, OnCallbackDestroyed());
|
| +
|
| + // Initialize, we expect to have no reads.
|
| + renderer_->Initialize(bad_decoder, callback_.NewCallback());
|
| + EXPECT_EQ(0u, read_queue_.size());
|
| +}
|
| +
|
| +// Test initialization where the subclass failed for some reason.
|
| +TEST_F(VideoRendererBaseTest, Initialize_Failed) {
|
| + InSequence s;
|
| +
|
| + // We expect the video size to be set.
|
| + EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
|
| +
|
| + // Our subclass will fail when asked to initialize.
|
| + EXPECT_CALL(*renderer_, OnInitialize(_))
|
| + .WillOnce(Return(false));
|
| +
|
| + // We expect to receive an error.
|
| + EXPECT_CALL(host_, Error(PIPELINE_ERROR_INITIALIZATION_FAILED));
|
| +
|
| + // We expect our callback to be executed.
|
| + EXPECT_CALL(callback_, OnFilterCallback());
|
| + EXPECT_CALL(callback_, OnCallbackDestroyed());
|
| +
|
| + // Initialize, we expect to have no reads.
|
| + renderer_->Initialize(decoder_, callback_.NewCallback());
|
| + EXPECT_EQ(0u, read_queue_.size());
|
| +}
|
| +
|
| +// Tests successful initialization, but when we immediately return an end of
|
| +// stream frame.
|
| +TEST_F(VideoRendererBaseTest, Initialize_NoData) {
|
| + InSequence s;
|
| +
|
| + // We expect the video size to be set.
|
| + EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
|
| +
|
| + // Then our subclass will be asked to initialize.
|
| + EXPECT_CALL(*renderer_, OnInitialize(_))
|
| + .WillOnce(Return(true));
|
| +
|
| + // Set up a check point to verify that the callback hasn't been executed yet.
|
| + EXPECT_CALL(*renderer_, CheckPoint(0));
|
| +
|
| + // We'll provide end-of-stream immediately, which results in an error.
|
| + EXPECT_CALL(host_, Error(PIPELINE_ERROR_NO_DATA));
|
| +
|
| + // Then we expect our callback to be executed.
|
| + EXPECT_CALL(callback_, OnFilterCallback());
|
| + EXPECT_CALL(callback_, OnCallbackDestroyed());
|
| +
|
| + // Since the callbacks are on a separate thread, expect any number of calls.
|
| + EXPECT_CALL(*renderer_, OnFrameAvailable())
|
| + .Times(AnyNumber());
|
| +
|
| + // Initialize, we should expect to get a bunch of read requests.
|
| + renderer_->Initialize(decoder_, callback_.NewCallback());
|
| + EXPECT_EQ(3u, read_queue_.size());
|
| +
|
| + // Verify our callback hasn't been executed yet.
|
| + renderer_->CheckPoint(0);
|
| +
|
| + // Now satisfy the read requests. Our callback should be executed after
|
| + // exiting this loop.
|
| + while (!read_queue_.empty()) {
|
| + const base::TimeDelta kZero;
|
| + scoped_refptr<VideoFrame> frame;
|
| + VideoFrameImpl::CreateEmptyFrame(&frame);
|
| + read_queue_.front()->Run(frame);
|
| + delete read_queue_.front();
|
| + read_queue_.pop_front();
|
| + }
|
| +}
|
| +
|
| +// Test successful initialization and preroll.
|
| +TEST_F(VideoRendererBaseTest, Initialize_Successful) {
|
| + InSequence s;
|
| +
|
| + // We expect the video size to be set.
|
| + EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
|
| +
|
| + // Then our subclass will be asked to initialize.
|
| + EXPECT_CALL(*renderer_, OnInitialize(_))
|
| + .WillOnce(Return(true));
|
| +
|
| + // Set up a check point to verify that the callback hasn't been executed yet.
|
| + EXPECT_CALL(*renderer_, CheckPoint(0));
|
| +
|
| + // After finishing preroll, we expect our callback to be executed.
|
| + EXPECT_CALL(callback_, OnFilterCallback());
|
| + EXPECT_CALL(callback_, OnCallbackDestroyed());
|
| +
|
| + // Since the callbacks are on a separate thread, expect any number of calls.
|
| + EXPECT_CALL(*renderer_, OnFrameAvailable())
|
| + .Times(AnyNumber());
|
| +
|
| + // Initialize, we should expect to get a bunch of read requests.
|
| + renderer_->Initialize(decoder_, callback_.NewCallback());
|
| + EXPECT_EQ(3u, read_queue_.size());
|
| +
|
| + // Verify our callback hasn't been executed yet.
|
| + renderer_->CheckPoint(0);
|
| +
|
| + // Now satisfy the read requests. Our callback should be executed after
|
| + // exiting this loop.
|
| + while (!read_queue_.empty()) {
|
| + const base::TimeDelta kZero;
|
| + scoped_refptr<VideoFrame> frame;
|
| + VideoFrameImpl::CreateFrame(VideoSurface::RGB32, kWidth, kHeight, kZero,
|
| + kZero, &frame);
|
| + read_queue_.front()->Run(frame);
|
| + delete read_queue_.front();
|
| + read_queue_.pop_front();
|
| + }
|
| +}
|
| +
|
| +} // namespace media
|
|
|