Chromium Code Reviews| 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. | |
|
damienv1
2014/10/03 22:19:41
I think the whole unit test has been updated in th
gunsch
2014/10/03 23:08:44
Huh, so it was. Updated.
| |
| 4 | |
| 5 #include <list> | |
| 6 #include <vector> | |
| 7 | |
| 8 #include "base/basictypes.h" | |
| 9 #include "base/bind.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/files/memory_mapped_file.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "base/memory/ref_counted.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/message_loop/message_loop.h" | |
| 16 #include "base/message_loop/message_loop_proxy.h" | |
| 17 #include "base/path_service.h" | |
| 18 #include "base/threading/thread.h" | |
| 19 #include "base/time/time.h" | |
| 20 #include "chromecast/media/cma/backend/audio_pipeline_device.h" | |
| 21 #include "chromecast/media/cma/backend/media_clock_device.h" | |
| 22 #include "chromecast/media/cma/backend/media_component_device_feeder_for_test.h" | |
| 23 #include "chromecast/media/cma/backend/media_pipeline_device.h" | |
| 24 #include "chromecast/media/cma/backend/video_pipeline_device.h" | |
| 25 #include "chromecast/media/cma/base/decoder_buffer_adapter.h" | |
| 26 #include "chromecast/media/cma/base/decoder_buffer_base.h" | |
| 27 #include "chromecast/media/cma/test/frame_segmenter_for_test.h" | |
| 28 #include "media/base/audio_decoder_config.h" | |
| 29 #include "media/base/buffers.h" | |
| 30 #include "media/base/decoder_buffer.h" | |
| 31 #include "media/base/video_decoder_config.h" | |
| 32 #include "testing/gtest/include/gtest/gtest.h" | |
| 33 | |
| 34 namespace chromecast { | |
| 35 namespace media { | |
| 36 | |
| 37 namespace { | |
| 38 | |
| 39 base::FilePath GetTestDataFilePath(const std::string& name) { | |
| 40 base::FilePath file_path; | |
| 41 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | |
| 42 | |
| 43 file_path = file_path.Append(FILE_PATH_LITERAL("media")) | |
| 44 .Append(FILE_PATH_LITERAL("test")) | |
| 45 .Append(FILE_PATH_LITERAL("data")) | |
| 46 .AppendASCII(name); | |
| 47 return file_path; | |
| 48 } | |
| 49 | |
| 50 } | |
| 51 | |
| 52 class AudioVideoPipelineDeviceTest : public testing::Test { | |
| 53 public: | |
| 54 AudioVideoPipelineDeviceTest(); | |
| 55 virtual ~AudioVideoPipelineDeviceTest(); | |
| 56 | |
| 57 void ConfigureForFile(std::string filename); | |
| 58 void ConfigureForAudioOnly(std::string filename); | |
| 59 void ConfigureForVideoOnly(std::string filename, | |
| 60 bool raw_h264); | |
| 61 | |
| 62 void Start(); | |
| 63 | |
| 64 private: | |
| 65 void Initialize(); | |
| 66 | |
| 67 void LoadAudioStream(std::string filename); | |
| 68 void LoadVideoStream(std::string filename, bool raw_h264); | |
| 69 | |
| 70 void OnPrimaryEos(); | |
| 71 | |
| 72 scoped_ptr<MediaPipelineDevice> media_pipeline_device_; | |
| 73 MediaClockDevice* media_clock_device_; | |
| 74 | |
| 75 // Devices to feed | |
| 76 std::vector<scoped_refptr<MediaComponentDeviceFeeder> > | |
| 77 component_device_feeders_; | |
| 78 | |
| 79 DISALLOW_COPY_AND_ASSIGN(AudioVideoPipelineDeviceTest); | |
| 80 }; | |
| 81 | |
| 82 AudioVideoPipelineDeviceTest::AudioVideoPipelineDeviceTest() { | |
| 83 } | |
| 84 | |
| 85 AudioVideoPipelineDeviceTest::~AudioVideoPipelineDeviceTest() { | |
| 86 } | |
| 87 | |
| 88 void AudioVideoPipelineDeviceTest::ConfigureForAudioOnly(std::string filename) { | |
| 89 Initialize(); | |
| 90 | |
| 91 LoadAudioStream(filename); | |
| 92 | |
| 93 component_device_feeders_[0]->SetFrameCountBetweenPause(50); | |
| 94 component_device_feeders_[0]->SetEosCB( | |
| 95 base::Bind(&AudioVideoPipelineDeviceTest::OnPrimaryEos, | |
| 96 base::Unretained(this))); | |
| 97 } | |
| 98 | |
| 99 void AudioVideoPipelineDeviceTest::ConfigureForVideoOnly(std::string filename, | |
| 100 bool raw_h264) { | |
| 101 Initialize(); | |
| 102 | |
| 103 LoadVideoStream(filename, raw_h264); | |
| 104 | |
| 105 component_device_feeders_[0]->SetFrameCountBetweenPause(50); | |
| 106 component_device_feeders_[0]->SetEosCB( | |
| 107 base::Bind(&AudioVideoPipelineDeviceTest::OnPrimaryEos, | |
| 108 base::Unretained(this))); | |
| 109 } | |
| 110 | |
| 111 void AudioVideoPipelineDeviceTest::ConfigureForFile(std::string filename) { | |
| 112 Initialize(); | |
| 113 | |
| 114 LoadVideoStream(filename, /* raw_h264 */ false); | |
| 115 LoadAudioStream(filename); | |
| 116 | |
| 117 component_device_feeders_[0]->SetFrameCountBetweenPause(50); | |
| 118 component_device_feeders_[0]->SetEosCB( | |
| 119 base::Bind(&AudioVideoPipelineDeviceTest::OnPrimaryEos, | |
| 120 base::Unretained(this))); | |
| 121 } | |
| 122 | |
| 123 void AudioVideoPipelineDeviceTest::LoadAudioStream(std::string filename) { | |
| 124 base::FilePath file_path = GetTestDataFilePath(filename); | |
| 125 DemuxResult demux_result = FFmpegDemuxForTest(file_path, /*audio*/ true); | |
| 126 std::list<scoped_refptr<DecoderBufferBase> > frames = demux_result.frames; | |
| 127 | |
| 128 AudioPipelineDevice *audio_pipeline_device = | |
| 129 media_pipeline_device_->GetAudioPipelineDevice(); | |
| 130 | |
| 131 // Set configuration. | |
| 132 bool success = audio_pipeline_device->SetConfig(demux_result.audio_config); | |
| 133 ASSERT_TRUE(success); | |
| 134 | |
| 135 VLOG(2) << "Got " << frames.size() << " audio input frames"; | |
| 136 | |
| 137 frames.push_back( | |
| 138 scoped_refptr<DecoderBufferBase>( | |
| 139 new DecoderBufferAdapter(::media::DecoderBuffer::CreateEOSBuffer()))); | |
| 140 | |
| 141 scoped_refptr<MediaComponentDeviceFeeder> new_feeder = | |
| 142 scoped_refptr<MediaComponentDeviceFeeder>( | |
| 143 new MediaComponentDeviceFeeder(audio_pipeline_device, | |
| 144 media_clock_device_, | |
| 145 frames)); | |
| 146 new_feeder->Initialize(); | |
| 147 | |
| 148 component_device_feeders_.push_back(new_feeder); | |
| 149 } | |
| 150 | |
| 151 void AudioVideoPipelineDeviceTest::LoadVideoStream(std::string filename, | |
| 152 bool raw_h264) { | |
| 153 std::list<scoped_refptr<DecoderBufferBase> > frames; | |
| 154 ::media::VideoDecoderConfig video_config; | |
| 155 | |
| 156 if (raw_h264) { | |
| 157 base::FilePath file_path = GetTestDataFilePath(filename); | |
| 158 base::MemoryMappedFile video_stream; | |
| 159 ASSERT_TRUE(video_stream.Initialize(file_path)) | |
| 160 << "Couldn't open stream file: " << file_path.MaybeAsASCII(); | |
| 161 frames = H264SegmenterForTest(video_stream.data(), video_stream.length()); | |
| 162 | |
| 163 // Use arbitraty sizes. | |
| 164 gfx::Size coded_size(320, 240); | |
| 165 gfx::Rect visible_rect(0, 0, 320, 240); | |
| 166 gfx::Size natural_size(320, 240); | |
| 167 | |
| 168 video_config = ::media::VideoDecoderConfig( | |
| 169 ::media::kCodecH264, | |
| 170 ::media::H264PROFILE_MAIN, | |
| 171 ::media::VideoFrame::I420, | |
| 172 coded_size, | |
| 173 visible_rect, | |
| 174 natural_size, | |
| 175 NULL, 0, false); | |
| 176 } else { | |
| 177 base::FilePath file_path = GetTestDataFilePath(filename); | |
| 178 DemuxResult demux_result = FFmpegDemuxForTest(file_path, | |
| 179 /*audio*/ false); | |
| 180 frames = demux_result.frames; | |
| 181 video_config = demux_result.video_config; | |
| 182 } | |
| 183 | |
| 184 VideoPipelineDevice *video_pipeline_device = | |
| 185 media_pipeline_device_->GetVideoPipelineDevice(); | |
| 186 | |
| 187 // Set configuration. | |
| 188 bool success = video_pipeline_device->SetConfig(video_config); | |
| 189 ASSERT_TRUE(success); | |
| 190 | |
| 191 VLOG(2) << "Got " << frames.size() << " video input frames"; | |
| 192 | |
| 193 frames.push_back( | |
| 194 scoped_refptr<DecoderBufferBase>(new DecoderBufferAdapter( | |
| 195 ::media::DecoderBuffer::CreateEOSBuffer()))); | |
| 196 | |
| 197 scoped_refptr<MediaComponentDeviceFeeder> new_feeder = | |
| 198 scoped_refptr<MediaComponentDeviceFeeder>( | |
| 199 new MediaComponentDeviceFeeder(video_pipeline_device, | |
| 200 media_clock_device_, | |
| 201 frames)); | |
| 202 new_feeder->Initialize(); | |
| 203 | |
| 204 component_device_feeders_.push_back(new_feeder); | |
| 205 } | |
| 206 | |
| 207 void AudioVideoPipelineDeviceTest::Start() { | |
| 208 for (int i=0; i < component_device_feeders_.size(); i++) { | |
| 209 base::MessageLoopProxy::current()->PostTask( | |
| 210 FROM_HERE, | |
| 211 base::Bind(&MediaComponentDeviceFeeder::Feed, | |
| 212 base::Unretained(component_device_feeders_[i].get()))); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void AudioVideoPipelineDeviceTest::OnPrimaryEos() { | |
| 217 base::MessageLoop::current()->QuitWhenIdle(); | |
| 218 } | |
| 219 | |
| 220 void AudioVideoPipelineDeviceTest::Initialize() { | |
| 221 // Create the media device. | |
| 222 MediaPipelineDevice::CreateParameters params; | |
| 223 media_pipeline_device_.reset(CreateMediaPipelineDevice(params).release()); | |
| 224 media_clock_device_ = media_pipeline_device_->GetMediaClockDevice(); | |
| 225 | |
| 226 // Clock initialization and configuration. | |
| 227 bool success = | |
| 228 media_clock_device_->SetState(MediaClockDevice::kStateIdle); | |
| 229 ASSERT_TRUE(success); | |
| 230 success = media_clock_device_->ResetTimeline(base::TimeDelta()); | |
| 231 ASSERT_TRUE(success); | |
| 232 media_clock_device_->SetRate(1.0); | |
| 233 } | |
| 234 | |
| 235 TEST_F(AudioVideoPipelineDeviceTest, Mp3Playback) { | |
| 236 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | |
| 237 | |
| 238 ConfigureForAudioOnly("sfx.mp3"); | |
| 239 Start(); | |
| 240 message_loop->Run(); | |
| 241 } | |
| 242 | |
| 243 TEST_F(AudioVideoPipelineDeviceTest, VorbisPlayback) { | |
| 244 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | |
| 245 | |
| 246 ConfigureForAudioOnly("sfx.ogg"); | |
| 247 Start(); | |
| 248 message_loop->Run(); | |
| 249 } | |
| 250 | |
| 251 TEST_F(AudioVideoPipelineDeviceTest, H264Playback) { | |
| 252 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | |
| 253 | |
| 254 ConfigureForVideoOnly("bear.h264", /* raw_h264 */ true); | |
|
damienv1
2014/10/03 22:19:41
Note: we introduce a dependency on Chrome test med
gunsch
2014/10/03 23:08:44
Only w.r.t header includes. Even gyp DEPS are okay
| |
| 255 Start(); | |
| 256 message_loop->Run(); | |
| 257 } | |
| 258 | |
| 259 TEST_F(AudioVideoPipelineDeviceTest, Vp8Playback) { | |
| 260 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | |
| 261 | |
| 262 ConfigureForVideoOnly("bear-vp8a.webm", /* raw_h264 */ false); | |
| 263 Start(); | |
| 264 message_loop->Run(); | |
| 265 } | |
| 266 | |
| 267 TEST_F(AudioVideoPipelineDeviceTest, VorbisAndVp8InWebmPlayback) { | |
| 268 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | |
| 269 | |
| 270 ConfigureForFile("bear-640x360.webm"); | |
| 271 Start(); | |
| 272 message_loop->Run(); | |
| 273 } | |
| 274 | |
| 275 } // namespace media | |
| 276 } // namespace chromecast | |
| OLD | NEW |