| Index: media/base/pipeline_unittest.cc
|
| diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
|
| index 1506c2194f7c29fe704cda9105a26f7b511d3fb6..1336c50230ac13751c16a58641082891d4382960 100644
|
| --- a/media/base/pipeline_unittest.cc
|
| +++ b/media/base/pipeline_unittest.cc
|
| @@ -11,11 +11,14 @@
|
| #include "base/threading/simple_thread.h"
|
| #include "base/time/clock.h"
|
| #include "media/base/clock.h"
|
| +#include "media/base/fake_text_track_stream.h"
|
| #include "media/base/gmock_callback_support.h"
|
| #include "media/base/media_log.h"
|
| #include "media/base/mock_filters.h"
|
| #include "media/base/pipeline.h"
|
| #include "media/base/test_helpers.h"
|
| +#include "media/base/text_renderer.h"
|
| +#include "media/base/text_track_config.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "ui/gfx/size.h"
|
|
|
| @@ -93,6 +96,13 @@ class PipelineTest : public ::testing::Test {
|
| scoped_ptr<AudioRenderer> audio_renderer(audio_renderer_);
|
| filter_collection_->SetAudioRenderer(audio_renderer.Pass());
|
|
|
| + text_renderer_ = new TextRenderer(
|
| + message_loop_.message_loop_proxy(),
|
| + base::Bind(&PipelineTest::OnAddTextTrack,
|
| + base::Unretained(this)));
|
| + scoped_ptr<TextRenderer> text_renderer(text_renderer_);
|
| + filter_collection_->SetTextRenderer(text_renderer.Pass());
|
| +
|
| // InitializeDemuxer() adds overriding expectations for expected non-NULL
|
| // streams.
|
| DemuxerStream* null_pointer = NULL;
|
| @@ -109,6 +119,13 @@ class PipelineTest : public ::testing::Test {
|
|
|
| ExpectStop();
|
|
|
| + // The mock demuxer doesn't stop the fake text track stream,
|
| + // so just stop it manually.
|
| + if (text_stream_) {
|
| + text_stream_->Stop();
|
| + message_loop_.RunUntilIdle();
|
| + }
|
| +
|
| // Expect a stop callback if we were started.
|
| EXPECT_CALL(callbacks_, OnStop());
|
| pipeline_->Stop(base::Bind(&CallbackHelper::OnStop,
|
| @@ -122,7 +139,7 @@ class PipelineTest : public ::testing::Test {
|
| void InitializeDemuxer(MockDemuxerStreamVector* streams,
|
| const base::TimeDelta& duration) {
|
| EXPECT_CALL(callbacks_, OnDurationChange());
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _))
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _))
|
| .WillOnce(DoAll(SetDemuxerProperties(duration),
|
| RunCallback<1>(PIPELINE_OK)));
|
|
|
| @@ -173,6 +190,13 @@ class PipelineTest : public ::testing::Test {
|
| }
|
| }
|
|
|
| + void AddTextStream() {
|
| + EXPECT_CALL(*this, OnAddTextTrack(_,_))
|
| + .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack));
|
| + static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(),
|
| + TextTrackConfig(kTextSubtitles, "", ""));
|
| + }
|
| +
|
| // Sets up expectations on the callback and initializes the pipeline. Called
|
| // after tests have set expectations any filters they wish to use.
|
| void InitializePipeline(PipelineStatus start_status) {
|
| @@ -215,6 +239,11 @@ class PipelineTest : public ::testing::Test {
|
| video_stream_->set_video_decoder_config(video_decoder_config_);
|
| }
|
|
|
| + void CreateTextStream() {
|
| + scoped_ptr<FakeTextTrackStream> text_stream(new FakeTextTrackStream);
|
| + text_stream_ = text_stream.Pass();
|
| + }
|
| +
|
| MockDemuxerStream* audio_stream() {
|
| return audio_stream_.get();
|
| }
|
| @@ -223,6 +252,10 @@ class PipelineTest : public ::testing::Test {
|
| return video_stream_.get();
|
| }
|
|
|
| + FakeTextTrackStream* text_stream() {
|
| + return text_stream_.get();
|
| + }
|
| +
|
| void ExpectSeek(const base::TimeDelta& seek_time) {
|
| // Every filter should receive a call to Seek().
|
| EXPECT_CALL(*demuxer_, Seek(seek_time, _))
|
| @@ -281,6 +314,15 @@ class PipelineTest : public ::testing::Test {
|
| EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
|
| }
|
|
|
| + MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&,
|
| + const AddTextTrackDoneCB&));
|
| +
|
| + void DoOnAddTextTrack(const TextTrackConfig& config,
|
| + const AddTextTrackDoneCB& done_cb) {
|
| + scoped_ptr<MockTextTrack> text_track(new MockTextTrack);
|
| + done_cb.Run(text_track.Pass());
|
| + }
|
| +
|
| // Fixture members.
|
| StrictMock<CallbackHelper> callbacks_;
|
| base::SimpleTestTickClock test_tick_clock_;
|
| @@ -291,8 +333,11 @@ class PipelineTest : public ::testing::Test {
|
| scoped_ptr<MockDemuxer> demuxer_;
|
| MockVideoRenderer* video_renderer_;
|
| MockAudioRenderer* audio_renderer_;
|
| + StrictMock<CallbackHelper> text_renderer_callbacks_;
|
| + TextRenderer* text_renderer_;
|
| scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
|
| scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
|
| + scoped_ptr<FakeTextTrackStream> text_stream_;
|
| AudioRenderer::TimeCB audio_time_cb_;
|
| VideoDecoderConfig video_decoder_config_;
|
|
|
| @@ -338,7 +383,7 @@ TEST_F(PipelineTest, NotStarted) {
|
|
|
| TEST_F(PipelineTest, NeverInitializes) {
|
| // Don't execute the callback passed into Initialize().
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _));
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _));
|
|
|
| // This test hangs during initialization by never calling
|
| // InitializationComplete(). StrictMock<> will ensure that the callback is
|
| @@ -363,7 +408,7 @@ TEST_F(PipelineTest, NeverInitializes) {
|
| }
|
|
|
| TEST_F(PipelineTest, URLNotFound) {
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _))
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _))
|
| .WillOnce(RunCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND));
|
| EXPECT_CALL(*demuxer_, Stop(_))
|
| .WillOnce(RunClosure<0>());
|
| @@ -372,7 +417,7 @@ TEST_F(PipelineTest, URLNotFound) {
|
| }
|
|
|
| TEST_F(PipelineTest, NoStreams) {
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _))
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _))
|
| .WillOnce(RunCallback<1>(PIPELINE_OK));
|
| EXPECT_CALL(*demuxer_, Stop(_))
|
| .WillOnce(RunClosure<0>());
|
| @@ -422,9 +467,47 @@ TEST_F(PipelineTest, AudioVideoStream) {
|
| EXPECT_TRUE(pipeline_->HasVideo());
|
| }
|
|
|
| +TEST_F(PipelineTest, VideoTextStream) {
|
| + CreateVideoStream();
|
| + CreateTextStream();
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(video_stream());
|
| +
|
| + InitializeDemuxer(&streams);
|
| + InitializeVideoRenderer(video_stream());
|
| +
|
| + InitializePipeline(PIPELINE_OK);
|
| + EXPECT_FALSE(pipeline_->HasAudio());
|
| + EXPECT_TRUE(pipeline_->HasVideo());
|
| +
|
| + AddTextStream();
|
| + message_loop_.RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(PipelineTest, VideoAudioTextStream) {
|
| + CreateVideoStream();
|
| + CreateAudioStream();
|
| + CreateTextStream();
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(video_stream());
|
| + streams.push_back(audio_stream());
|
| +
|
| + InitializeDemuxer(&streams);
|
| + InitializeVideoRenderer(video_stream());
|
| + InitializeAudioRenderer(audio_stream(), false);
|
| +
|
| + InitializePipeline(PIPELINE_OK);
|
| + EXPECT_TRUE(pipeline_->HasAudio());
|
| + EXPECT_TRUE(pipeline_->HasVideo());
|
| +
|
| + AddTextStream();
|
| + message_loop_.RunUntilIdle();
|
| +}
|
| +
|
| TEST_F(PipelineTest, Seek) {
|
| CreateAudioStream();
|
| CreateVideoStream();
|
| + CreateTextStream();
|
| MockDemuxerStreamVector streams;
|
| streams.push_back(audio_stream());
|
| streams.push_back(video_stream());
|
| @@ -436,6 +519,9 @@ TEST_F(PipelineTest, Seek) {
|
| // Initialize then seek!
|
| InitializePipeline(PIPELINE_OK);
|
|
|
| + AddTextStream();
|
| + message_loop_.RunUntilIdle();
|
| +
|
| // Every filter should receive a call to Seek().
|
| base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
|
| ExpectSeek(expected);
|
| @@ -574,6 +660,7 @@ TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
|
| TEST_F(PipelineTest, EndedCallback) {
|
| CreateAudioStream();
|
| CreateVideoStream();
|
| + CreateTextStream();
|
| MockDemuxerStreamVector streams;
|
| streams.push_back(audio_stream());
|
| streams.push_back(video_stream());
|
| @@ -583,13 +670,18 @@ TEST_F(PipelineTest, EndedCallback) {
|
| InitializeVideoRenderer(video_stream());
|
| InitializePipeline(PIPELINE_OK);
|
|
|
| - // The ended callback shouldn't run until both renderers have ended.
|
| + AddTextStream();
|
| +
|
| + // The ended callback shouldn't run until all renderers have ended.
|
| pipeline_->OnAudioRendererEnded();
|
| message_loop_.RunUntilIdle();
|
|
|
| - EXPECT_CALL(callbacks_, OnEnded());
|
| pipeline_->OnVideoRendererEnded();
|
| message_loop_.RunUntilIdle();
|
| +
|
| + EXPECT_CALL(callbacks_, OnEnded());
|
| + text_stream()->SendEosNotification();
|
| + message_loop_.RunUntilIdle();
|
| }
|
|
|
| TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
|
| @@ -923,13 +1015,13 @@ class PipelineTeardownTest : public PipelineTest {
|
|
|
| if (state == kInitDemuxer) {
|
| if (stop_or_error == kStop) {
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _))
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _))
|
| .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
|
| RunCallback<1>(PIPELINE_OK)));
|
| EXPECT_CALL(callbacks_, OnStop());
|
| } else {
|
| status = DEMUXER_ERROR_COULD_NOT_OPEN;
|
| - EXPECT_CALL(*demuxer_, Initialize(_, _))
|
| + EXPECT_CALL(*demuxer_, Initialize(_, _, _))
|
| .WillOnce(RunCallback<1>(status));
|
| }
|
|
|
|
|