| Index: media/filters/renderer_impl_unittest.cc
|
| diff --git a/media/filters/renderer_impl_unittest.cc b/media/filters/renderer_impl_unittest.cc
|
| deleted file mode 100644
|
| index d8bb49ef815332354cea465841495ebad518aad0..0000000000000000000000000000000000000000
|
| --- a/media/filters/renderer_impl_unittest.cc
|
| +++ /dev/null
|
| @@ -1,445 +0,0 @@
|
| -// Copyright 2014 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 <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/test/simple_test_tick_clock.h"
|
| -#include "media/base/gmock_callback_support.h"
|
| -#include "media/base/mock_filters.h"
|
| -#include "media/base/test_helpers.h"
|
| -#include "media/filters/renderer_impl.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using ::testing::_;
|
| -using ::testing::DoAll;
|
| -using ::testing::InSequence;
|
| -using ::testing::Mock;
|
| -using ::testing::Return;
|
| -using ::testing::SaveArg;
|
| -using ::testing::StrictMock;
|
| -
|
| -namespace media {
|
| -
|
| -const int64 kStartPlayingTimeInMs = 100;
|
| -
|
| -ACTION_P2(SetBufferingState, cb, buffering_state) {
|
| - cb->Run(buffering_state);
|
| -}
|
| -
|
| -ACTION_P2(AudioError, cb, error) {
|
| - cb->Run(error);
|
| -}
|
| -
|
| -class RendererImplTest : public ::testing::Test {
|
| - public:
|
| - // Used for setting expectations on pipeline callbacks. Using a StrictMock
|
| - // also lets us test for missing callbacks.
|
| - class CallbackHelper {
|
| - public:
|
| - CallbackHelper() {}
|
| - virtual ~CallbackHelper() {}
|
| -
|
| - MOCK_METHOD1(OnInitialize, void(PipelineStatus));
|
| - MOCK_METHOD0(OnFlushed, void());
|
| - MOCK_METHOD0(OnEnded, void());
|
| - MOCK_METHOD1(OnError, void(PipelineStatus));
|
| - MOCK_METHOD1(OnUpdateStatistics, void(const PipelineStatistics&));
|
| - MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
|
| - MOCK_METHOD1(OnVideoFramePaint, void(const scoped_refptr<VideoFrame>&));
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
|
| - };
|
| -
|
| - RendererImplTest()
|
| - : demuxer_(new StrictMock<MockDemuxer>()),
|
| - video_renderer_(new StrictMock<MockVideoRenderer>()),
|
| - audio_renderer_(new StrictMock<MockAudioRenderer>()),
|
| - renderer_impl_(
|
| - new RendererImpl(message_loop_.message_loop_proxy(),
|
| - scoped_ptr<AudioRenderer>(audio_renderer_),
|
| - scoped_ptr<VideoRenderer>(video_renderer_))) {
|
| - // SetDemuxerExpectations() adds overriding expectations for expected
|
| - // non-NULL streams.
|
| - DemuxerStream* null_pointer = NULL;
|
| - EXPECT_CALL(*demuxer_, GetStream(_))
|
| - .WillRepeatedly(Return(null_pointer));
|
| - }
|
| -
|
| - virtual ~RendererImplTest() {
|
| - renderer_impl_.reset();
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| -
|
| - protected:
|
| - typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
|
| -
|
| - scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream(
|
| - DemuxerStream::Type type) {
|
| - scoped_ptr<StrictMock<MockDemuxerStream> > stream(
|
| - new StrictMock<MockDemuxerStream>(type));
|
| - return stream.Pass();
|
| - }
|
| -
|
| - // Sets up expectations to allow the audio renderer to initialize.
|
| - void SetAudioRendererInitializeExpectations(PipelineStatus status) {
|
| - EXPECT_CALL(*audio_renderer_,
|
| - Initialize(audio_stream_.get(), _, _, _, _, _, _))
|
| - .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_),
|
| - SaveArg<5>(&audio_ended_cb_),
|
| - SaveArg<6>(&audio_error_cb_), RunCallback<1>(status)));
|
| - }
|
| -
|
| - // Sets up expectations to allow the video renderer to initialize.
|
| - void SetVideoRendererInitializeExpectations(PipelineStatus status) {
|
| - EXPECT_CALL(*video_renderer_,
|
| - Initialize(video_stream_.get(), _, _, _, _, _, _, _, _))
|
| - .WillOnce(DoAll(SaveArg<4>(&video_buffering_state_cb_),
|
| - SaveArg<6>(&video_ended_cb_), RunCallback<1>(status)));
|
| - }
|
| -
|
| - void InitializeAndExpect(PipelineStatus start_status) {
|
| - EXPECT_CALL(callbacks_, OnInitialize(start_status));
|
| -
|
| - if (start_status == PIPELINE_OK && audio_stream_) {
|
| - EXPECT_CALL(*audio_renderer_, GetTimeSource())
|
| - .WillOnce(Return(&time_source_));
|
| - }
|
| -
|
| - renderer_impl_->Initialize(
|
| - demuxer_.get(),
|
| - base::Bind(&CallbackHelper::OnInitialize,
|
| - base::Unretained(&callbacks_)),
|
| - base::Bind(&CallbackHelper::OnUpdateStatistics,
|
| - base::Unretained(&callbacks_)),
|
| - base::Bind(&CallbackHelper::OnBufferingStateChange,
|
| - base::Unretained(&callbacks_)),
|
| - base::Bind(&CallbackHelper::OnVideoFramePaint,
|
| - base::Unretained(&callbacks_)),
|
| - base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
|
| - base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)));
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| -
|
| - void CreateAudioStream() {
|
| - audio_stream_ = CreateStream(DemuxerStream::AUDIO);
|
| - streams_.push_back(audio_stream_.get());
|
| - EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO))
|
| - .WillRepeatedly(Return(audio_stream_.get()));
|
| - }
|
| -
|
| - void CreateVideoStream() {
|
| - video_stream_ = CreateStream(DemuxerStream::VIDEO);
|
| - video_stream_->set_video_decoder_config(video_decoder_config_);
|
| - streams_.push_back(video_stream_.get());
|
| - EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO))
|
| - .WillRepeatedly(Return(video_stream_.get()));
|
| - }
|
| -
|
| - void CreateAudioAndVideoStream() {
|
| - CreateAudioStream();
|
| - CreateVideoStream();
|
| - }
|
| -
|
| - void InitializeWithAudio() {
|
| - CreateAudioStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| - InitializeAndExpect(PIPELINE_OK);
|
| - }
|
| -
|
| - void InitializeWithVideo() {
|
| - CreateVideoStream();
|
| - SetVideoRendererInitializeExpectations(PIPELINE_OK);
|
| - InitializeAndExpect(PIPELINE_OK);
|
| - }
|
| -
|
| - void InitializeWithAudioAndVideo() {
|
| - CreateAudioAndVideoStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| - SetVideoRendererInitializeExpectations(PIPELINE_OK);
|
| - InitializeAndExpect(PIPELINE_OK);
|
| - }
|
| -
|
| - void Play() {
|
| - DCHECK(audio_stream_ || video_stream_);
|
| - EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
|
| -
|
| - base::TimeDelta start_time(
|
| - base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs));
|
| -
|
| - if (audio_stream_) {
|
| - EXPECT_CALL(time_source_, SetMediaTime(start_time));
|
| - EXPECT_CALL(time_source_, StartTicking());
|
| - EXPECT_CALL(*audio_renderer_, StartPlaying())
|
| - .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
|
| - BUFFERING_HAVE_ENOUGH));
|
| - }
|
| -
|
| - if (video_stream_) {
|
| - EXPECT_CALL(*video_renderer_, StartPlayingFrom(start_time))
|
| - .WillOnce(SetBufferingState(&video_buffering_state_cb_,
|
| - BUFFERING_HAVE_ENOUGH));
|
| - }
|
| -
|
| - renderer_impl_->StartPlayingFrom(start_time);
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| -
|
| - void Flush(bool underflowed) {
|
| - if (audio_stream_) {
|
| - if (!underflowed)
|
| - EXPECT_CALL(time_source_, StopTicking());
|
| - EXPECT_CALL(*audio_renderer_, Flush(_))
|
| - .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
|
| - BUFFERING_HAVE_NOTHING),
|
| - RunClosure<0>()));
|
| - }
|
| -
|
| - if (video_stream_) {
|
| - EXPECT_CALL(*video_renderer_, Flush(_))
|
| - .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_,
|
| - BUFFERING_HAVE_NOTHING),
|
| - RunClosure<0>()));
|
| - }
|
| -
|
| - EXPECT_CALL(callbacks_, OnFlushed());
|
| -
|
| - renderer_impl_->Flush(
|
| - base::Bind(&CallbackHelper::OnFlushed, base::Unretained(&callbacks_)));
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| -
|
| - void SetPlaybackRate(float playback_rate) {
|
| - EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
|
| - renderer_impl_->SetPlaybackRate(playback_rate);
|
| - base::RunLoop().RunUntilIdle();
|
| - }
|
| -
|
| - int64 GetMediaTimeMs() {
|
| - return renderer_impl_->GetMediaTime().InMilliseconds();
|
| - }
|
| -
|
| - bool IsMediaTimeAdvancing(float playback_rate) {
|
| - int64 start_time_ms = GetMediaTimeMs();
|
| - const int64 time_to_advance_ms = 100;
|
| -
|
| - test_tick_clock_.Advance(
|
| - base::TimeDelta::FromMilliseconds(time_to_advance_ms));
|
| -
|
| - if (GetMediaTimeMs() == start_time_ms + time_to_advance_ms * playback_rate)
|
| - return true;
|
| -
|
| - DCHECK_EQ(start_time_ms, GetMediaTimeMs());
|
| - return false;
|
| - }
|
| -
|
| - bool IsMediaTimeAdvancing() {
|
| - return IsMediaTimeAdvancing(1.0f);
|
| - }
|
| -
|
| - // Fixture members.
|
| - base::MessageLoop message_loop_;
|
| - StrictMock<CallbackHelper> callbacks_;
|
| - base::SimpleTestTickClock test_tick_clock_;
|
| -
|
| - scoped_ptr<StrictMock<MockDemuxer> > demuxer_;
|
| - StrictMock<MockVideoRenderer>* video_renderer_;
|
| - StrictMock<MockAudioRenderer>* audio_renderer_;
|
| - scoped_ptr<RendererImpl> renderer_impl_;
|
| -
|
| - StrictMock<MockTimeSource> time_source_;
|
| - scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
|
| - scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
|
| - MockDemuxerStreamVector streams_;
|
| - BufferingStateCB audio_buffering_state_cb_;
|
| - BufferingStateCB video_buffering_state_cb_;
|
| - base::Closure audio_ended_cb_;
|
| - base::Closure video_ended_cb_;
|
| - PipelineStatusCB audio_error_cb_;
|
| - VideoDecoderConfig video_decoder_config_;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(RendererImplTest);
|
| -};
|
| -
|
| -TEST_F(RendererImplTest, DestroyBeforeInitialize) {
|
| - // |renderer_impl_| will be destroyed in the dtor.
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithAudio) {
|
| - InitializeWithAudio();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithVideo) {
|
| - InitializeWithVideo();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithAudioVideo) {
|
| - InitializeWithAudioAndVideo();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithAudio_Failed) {
|
| - CreateAudioStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| - InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithVideo_Failed) {
|
| - CreateVideoStream();
|
| - SetVideoRendererInitializeExpectations(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| - InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithAudioVideo_AudioRendererFailed) {
|
| - CreateAudioAndVideoStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| - // VideoRenderer::Initialize() should not be called.
|
| - InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, InitializeWithAudioVideo_VideoRendererFailed) {
|
| - CreateAudioAndVideoStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| - SetVideoRendererInitializeExpectations(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| - InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, StartPlayingFrom) {
|
| - InitializeWithAudioAndVideo();
|
| - Play();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, FlushAfterInitialization) {
|
| - InitializeWithAudioAndVideo();
|
| - Flush(true);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, FlushAfterPlay) {
|
| - InitializeWithAudioAndVideo();
|
| - Play();
|
| - Flush(false);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, FlushAfterUnderflow) {
|
| - InitializeWithAudioAndVideo();
|
| - Play();
|
| -
|
| - // Simulate underflow.
|
| - EXPECT_CALL(time_source_, StopTicking());
|
| - audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING);
|
| -
|
| - // Flush while underflowed. We shouldn't call StopTicking() again.
|
| - Flush(true);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, SetPlaybackRate) {
|
| - InitializeWithAudioAndVideo();
|
| - SetPlaybackRate(1.0f);
|
| - SetPlaybackRate(2.0f);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, SetVolume) {
|
| - InitializeWithAudioAndVideo();
|
| - EXPECT_CALL(*audio_renderer_, SetVolume(2.0f));
|
| - renderer_impl_->SetVolume(2.0f);
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, AudioStreamEnded) {
|
| - InitializeWithAudio();
|
| - Play();
|
| -
|
| - EXPECT_CALL(time_source_, StopTicking());
|
| - EXPECT_CALL(callbacks_, OnEnded());
|
| -
|
| - audio_ended_cb_.Run();
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, VideoStreamEnded) {
|
| - InitializeWithVideo();
|
| - Play();
|
| -
|
| - // Video ended won't affect |time_source_|.
|
| - EXPECT_CALL(callbacks_, OnEnded());
|
| -
|
| - video_ended_cb_.Run();
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, AudioVideoStreamsEnded) {
|
| - InitializeWithAudioAndVideo();
|
| - Play();
|
| -
|
| - // OnEnded() is called only when all streams have finished.
|
| - audio_ended_cb_.Run();
|
| - base::RunLoop().RunUntilIdle();
|
| -
|
| - EXPECT_CALL(time_source_, StopTicking());
|
| - EXPECT_CALL(callbacks_, OnEnded());
|
| -
|
| - video_ended_cb_.Run();
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, ErrorAfterInitialize) {
|
| - InitializeWithAudio();
|
| - EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE));
|
| - audio_error_cb_.Run(PIPELINE_ERROR_DECODE);
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, ErrorDuringPlaying) {
|
| - InitializeWithAudio();
|
| - Play();
|
| -
|
| - EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE));
|
| - audio_error_cb_.Run(PIPELINE_ERROR_DECODE);
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, ErrorDuringFlush) {
|
| - InitializeWithAudio();
|
| - Play();
|
| -
|
| - InSequence s;
|
| - EXPECT_CALL(time_source_, StopTicking());
|
| - EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(DoAll(
|
| - AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE),
|
| - RunClosure<0>()));
|
| - EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE));
|
| - EXPECT_CALL(callbacks_, OnFlushed());
|
| - renderer_impl_->Flush(
|
| - base::Bind(&CallbackHelper::OnFlushed, base::Unretained(&callbacks_)));
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, ErrorAfterFlush) {
|
| - InitializeWithAudio();
|
| - Play();
|
| - Flush(false);
|
| -
|
| - EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE));
|
| - audio_error_cb_.Run(PIPELINE_ERROR_DECODE);
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -TEST_F(RendererImplTest, ErrorDuringInitialize) {
|
| - CreateAudioAndVideoStream();
|
| - SetAudioRendererInitializeExpectations(PIPELINE_OK);
|
| -
|
| - // Force an audio error to occur during video renderer initialization.
|
| - EXPECT_CALL(*video_renderer_,
|
| - Initialize(video_stream_.get(), _, _, _, _, _, _, _, _))
|
| - .WillOnce(DoAll(AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE),
|
| - SaveArg<4>(&video_buffering_state_cb_),
|
| - SaveArg<6>(&video_ended_cb_),
|
| - RunCallback<1>(PIPELINE_OK)));
|
| -
|
| - InitializeAndExpect(PIPELINE_ERROR_DECODE);
|
| -}
|
| -
|
| -} // namespace media
|
|
|