OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <vector> |
| 6 |
| 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" |
| 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/message_loop/message_loop_proxy.h" |
| 13 #include "base/time/time.h" |
| 14 #include "chromecast/media/cma/backend/audio_pipeline_device.h" |
| 15 #include "chromecast/media/cma/backend/media_clock_device.h" |
| 16 #include "chromecast/media/cma/backend/media_pipeline_device.h" |
| 17 #include "chromecast/media/cma/backend/media_pipeline_device_fake.h" |
| 18 #include "chromecast/media/cma/base/buffering_controller.h" |
| 19 #include "chromecast/media/cma/base/decoder_buffer_base.h" |
| 20 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h" |
| 21 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" |
| 22 #include "chromecast/media/cma/pipeline/media_pipeline_impl.h" |
| 23 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" |
| 24 #include "chromecast/media/cma/pipeline/video_pipeline_impl.h" |
| 25 #include "chromecast/media/cma/test/frame_generator_for_test.h" |
| 26 #include "chromecast/media/cma/test/mock_frame_provider.h" |
| 27 #include "media/base/audio_decoder_config.h" |
| 28 #include "media/base/buffers.h" |
| 29 #include "media/base/decoder_buffer.h" |
| 30 #include "media/base/video_decoder_config.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" |
| 32 |
| 33 namespace chromecast { |
| 34 namespace media { |
| 35 |
| 36 class AudioVideoPipelineImplTest : public testing::Test { |
| 37 public: |
| 38 AudioVideoPipelineImplTest(); |
| 39 virtual ~AudioVideoPipelineImplTest(); |
| 40 |
| 41 void Initialize(const base::Closure& done_cb, |
| 42 ::media::PipelineStatus status, |
| 43 bool is_audio); |
| 44 void StartPlaying(const base::Closure& done_cb, |
| 45 ::media::PipelineStatus status); |
| 46 |
| 47 void Flush(const base::Closure& done_cb, ::media::PipelineStatus status); |
| 48 void Stop(const base::Closure& done_cb, ::media::PipelineStatus status); |
| 49 |
| 50 void OnEos(); |
| 51 |
| 52 base::Closure task_after_eos_cb_; |
| 53 |
| 54 private: |
| 55 scoped_ptr<MediaPipelineImpl> media_pipeline_; |
| 56 |
| 57 DISALLOW_COPY_AND_ASSIGN(AudioVideoPipelineImplTest); |
| 58 }; |
| 59 |
| 60 AudioVideoPipelineImplTest::AudioVideoPipelineImplTest() |
| 61 : media_pipeline_(new MediaPipelineImpl()) { |
| 62 scoped_ptr<MediaPipelineDevice> media_pipeline_device( |
| 63 new MediaPipelineDeviceFake()); |
| 64 media_pipeline_->Initialize(kLoadTypeURL, media_pipeline_device.Pass()); |
| 65 media_pipeline_->SetPlaybackRate(1.0); |
| 66 } |
| 67 |
| 68 AudioVideoPipelineImplTest::~AudioVideoPipelineImplTest() { |
| 69 } |
| 70 |
| 71 void AudioVideoPipelineImplTest::Initialize( |
| 72 const base::Closure& done_cb, |
| 73 ::media::PipelineStatus status, |
| 74 bool is_audio) { |
| 75 if (is_audio) { |
| 76 AvPipelineClient client; |
| 77 client.eos_cb = |
| 78 base::Bind(&AudioVideoPipelineImplTest::OnEos, base::Unretained(this)); |
| 79 media_pipeline_->GetAudioPipeline()->SetClient(client); |
| 80 } else { |
| 81 VideoPipelineClient client; |
| 82 client.av_pipeline_client.eos_cb = |
| 83 base::Bind(&AudioVideoPipelineImplTest::OnEos, base::Unretained(this)); |
| 84 media_pipeline_->GetVideoPipeline()->SetClient(client); |
| 85 } |
| 86 |
| 87 ::media::AudioDecoderConfig audio_config( |
| 88 ::media::kCodecMP3, |
| 89 ::media::kSampleFormatS16, |
| 90 ::media::CHANNEL_LAYOUT_STEREO, |
| 91 44100, |
| 92 NULL, 0, false); |
| 93 ::media::VideoDecoderConfig video_config( |
| 94 ::media::kCodecH264, |
| 95 ::media::H264PROFILE_MAIN, |
| 96 ::media::VideoFrame::I420, |
| 97 gfx::Size(640, 480), |
| 98 gfx::Rect(0, 0, 640, 480), |
| 99 gfx::Size(640, 480), |
| 100 NULL, 0, false); |
| 101 |
| 102 // Frame generation on the producer side. |
| 103 std::vector<FrameGeneratorForTest::FrameSpec> frame_specs; |
| 104 frame_specs.resize(100); |
| 105 for (size_t k = 0; k < frame_specs.size() - 1; k++) { |
| 106 frame_specs[k].has_config = (k == 0); |
| 107 frame_specs[k].timestamp = base::TimeDelta::FromMilliseconds(40) * k; |
| 108 frame_specs[k].size = 512; |
| 109 frame_specs[k].has_decrypt_config = false; |
| 110 } |
| 111 frame_specs[frame_specs.size() - 1].is_eos = true; |
| 112 |
| 113 scoped_ptr<FrameGeneratorForTest> frame_generator_provider( |
| 114 new FrameGeneratorForTest(frame_specs)); |
| 115 bool provider_delayed_pattern[] = { true, false }; |
| 116 scoped_ptr<MockFrameProvider> frame_provider(new MockFrameProvider()); |
| 117 frame_provider->Configure( |
| 118 std::vector<bool>( |
| 119 provider_delayed_pattern, |
| 120 provider_delayed_pattern + arraysize(provider_delayed_pattern)), |
| 121 frame_generator_provider.Pass()); |
| 122 |
| 123 ::media::PipelineStatusCB next_task = |
| 124 base::Bind(&AudioVideoPipelineImplTest::StartPlaying, |
| 125 base::Unretained(this), |
| 126 done_cb); |
| 127 |
| 128 scoped_ptr<CodedFrameProvider> frame_provider_base(frame_provider.release()); |
| 129 base::Closure task = is_audio ? |
| 130 base::Bind(&MediaPipeline::InitializeAudio, |
| 131 base::Unretained(media_pipeline_.get()), |
| 132 audio_config, |
| 133 base::Passed(&frame_provider_base), |
| 134 next_task) : |
| 135 base::Bind(&MediaPipeline::InitializeVideo, |
| 136 base::Unretained(media_pipeline_.get()), |
| 137 video_config, |
| 138 base::Passed(&frame_provider_base), |
| 139 next_task); |
| 140 |
| 141 base::MessageLoopProxy::current()->PostTask(FROM_HERE, task); |
| 142 } |
| 143 |
| 144 void AudioVideoPipelineImplTest::StartPlaying( |
| 145 const base::Closure& done_cb, ::media::PipelineStatus status) { |
| 146 base::TimeDelta start_time = base::TimeDelta::FromMilliseconds(0); |
| 147 |
| 148 media_pipeline_->StartPlayingFrom(start_time); |
| 149 if (!done_cb.is_null()) |
| 150 done_cb.Run(); |
| 151 } |
| 152 |
| 153 void AudioVideoPipelineImplTest::OnEos() { |
| 154 task_after_eos_cb_.Run(); |
| 155 } |
| 156 |
| 157 void AudioVideoPipelineImplTest::Flush( |
| 158 const base::Closure& done_cb, ::media::PipelineStatus status) { |
| 159 ::media::PipelineStatusCB next_task = |
| 160 base::Bind(&AudioVideoPipelineImplTest::Stop, base::Unretained(this), |
| 161 done_cb); |
| 162 base::MessageLoopProxy::current()->PostTask( |
| 163 FROM_HERE, |
| 164 base::Bind(&MediaPipeline::Flush, |
| 165 base::Unretained(media_pipeline_.get()), |
| 166 next_task)); |
| 167 } |
| 168 |
| 169 void AudioVideoPipelineImplTest::Stop( |
| 170 const base::Closure& done_cb, ::media::PipelineStatus status) { |
| 171 media_pipeline_->Stop(); |
| 172 if (!done_cb.is_null()) |
| 173 done_cb.Run(); |
| 174 base::MessageLoop::current()->QuitWhenIdle(); |
| 175 } |
| 176 |
| 177 |
| 178 TEST_F(AudioVideoPipelineImplTest, AudioFullCycleInitToStop) { |
| 179 bool is_audio = true; |
| 180 task_after_eos_cb_ = base::Bind( |
| 181 &AudioVideoPipelineImplTest::Flush, base::Unretained(this), |
| 182 base::Closure(), ::media::PIPELINE_OK); |
| 183 |
| 184 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| 185 message_loop->PostTask( |
| 186 FROM_HERE, |
| 187 base::Bind(&AudioVideoPipelineImplTest::Initialize, |
| 188 base::Unretained(this), |
| 189 base::Closure(), |
| 190 ::media::PIPELINE_OK, is_audio)); |
| 191 message_loop->Run(); |
| 192 }; |
| 193 |
| 194 TEST_F(AudioVideoPipelineImplTest, VideoFullCycleInitToStop) { |
| 195 bool is_audio = false; |
| 196 task_after_eos_cb_ = base::Bind( |
| 197 &AudioVideoPipelineImplTest::Flush, base::Unretained(this), |
| 198 base::Closure(), ::media::PIPELINE_OK); |
| 199 |
| 200 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| 201 message_loop->PostTask( |
| 202 FROM_HERE, |
| 203 base::Bind(&AudioVideoPipelineImplTest::Initialize, |
| 204 base::Unretained(this), |
| 205 base::Closure(), |
| 206 ::media::PIPELINE_OK, is_audio)); |
| 207 message_loop->Run(); |
| 208 }; |
| 209 |
| 210 } // namespace media |
| 211 } // namespace chromecast |
OLD | NEW |