OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 | 6 |
7 #include "base/singleton.h" | 7 #include "base/singleton.h" |
8 #include "base/tuple.h" | 8 #include "base/tuple.h" |
9 #include "media/base/filter_host.h" | 9 #include "media/base/filter_host.h" |
10 #include "media/base/filters.h" | 10 #include "media/base/filters.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 g_seek_event->Signal(); | 158 g_seek_event->Signal(); |
159 return g_av_seek_frame; | 159 return g_av_seek_frame; |
160 } | 160 } |
161 | 161 |
162 } // extern "C" | 162 } // extern "C" |
163 | 163 |
164 using namespace media; | 164 using namespace media; |
165 | 165 |
166 namespace { | 166 namespace { |
167 | 167 |
168 void InitializeFFmpegMocks() { | |
169 // Initialize function return codes. | |
170 g_av_open_input_file = 0; | |
171 g_av_find_stream_info = 0; | |
172 g_av_read_frame = 0; | |
173 | |
174 // Initialize AVFormatContext structure. | |
175 memset(&g_format, 0, sizeof(g_format)); | |
176 | |
177 // Initialize AVStream structures. | |
178 for (size_t i = 0; i < kMaxStreams; ++i) { | |
179 memset(&g_streams[i], 0, sizeof(g_streams[i])); | |
180 g_streams[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; | |
181 g_streams[i].time_base.num = 1; | |
182 } | |
183 | |
184 // Initialize AVCodexContext structures. | |
185 memset(&g_audio_codec, 0, sizeof(g_audio_codec)); | |
186 g_audio_codec.codec_type = CODEC_TYPE_AUDIO; | |
187 g_audio_codec.codec_id = CODEC_ID_VORBIS; | |
188 g_audio_codec.channels = 2; | |
189 g_audio_codec.sample_rate = 44100; | |
190 | |
191 memset(&g_video_codec, 0, sizeof(g_video_codec)); | |
192 g_video_codec.codec_type = CODEC_TYPE_VIDEO; | |
193 g_video_codec.codec_id = CODEC_ID_THEORA; | |
194 g_video_codec.height = 720; | |
195 g_video_codec.width = 1280; | |
196 | |
197 memset(&g_data_codec, 0, sizeof(g_data_codec)); | |
198 g_data_codec.codec_type = CODEC_TYPE_DATA; | |
199 g_data_codec.codec_id = CODEC_ID_NONE; | |
200 } | |
201 | |
202 // Ref counted object so we can create callbacks to call DemuxerStream::Read(). | 168 // Ref counted object so we can create callbacks to call DemuxerStream::Read(). |
203 class TestReader : public base::RefCountedThreadSafe<TestReader> { | 169 class TestReader : public base::RefCountedThreadSafe<TestReader> { |
204 public: | 170 public: |
205 TestReader() | 171 TestReader() |
206 : called_(false), | 172 : called_(false), |
207 expecting_call_(false), | 173 expecting_call_(false), |
208 wait_for_read_(false, false) { | 174 wait_for_read_(false, false) { |
209 } | 175 } |
210 | 176 |
211 virtual ~TestReader() {} | 177 virtual ~TestReader() {} |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 bool called() { return called_; } | 209 bool called() { return called_; } |
244 bool expecting_call() { return expecting_call_; } | 210 bool expecting_call() { return expecting_call_; } |
245 | 211 |
246 private: | 212 private: |
247 scoped_refptr<Buffer> buffer_; | 213 scoped_refptr<Buffer> buffer_; |
248 bool called_; | 214 bool called_; |
249 bool expecting_call_; | 215 bool expecting_call_; |
250 base::WaitableEvent wait_for_read_; | 216 base::WaitableEvent wait_for_read_; |
251 }; | 217 }; |
252 | 218 |
| 219 // Fixture class to facilitate writing tests. Takes care of setting up the |
| 220 // FFmpeg, pipeline and filter host mocks. |
| 221 class FFmpegDemuxerTest : public testing::Test { |
| 222 protected: |
| 223 FFmpegDemuxerTest() {} |
| 224 virtual ~FFmpegDemuxerTest() {} |
| 225 |
| 226 virtual void SetUp() { |
| 227 InitializeFFmpegMocks(); |
| 228 |
| 229 // Create an FFmpegDemuxer. |
| 230 factory_ = FFmpegDemuxer::CreateFilterFactory(); |
| 231 MediaFormat media_format; |
| 232 media_format.SetAsString(MediaFormat::kMimeType, |
| 233 mime_type::kApplicationOctetStream); |
| 234 demuxer_ = factory_->Create<Demuxer>(media_format); |
| 235 DCHECK(demuxer_); |
| 236 |
| 237 // Prepare a filter host and data source for the demuxer. |
| 238 pipeline_.reset(new MockPipeline()); |
| 239 filter_host_.reset(new MockFilterHost<Demuxer>(pipeline_.get(), demuxer_)); |
| 240 MockFilterConfig config; |
| 241 data_source_ = new MockDataSource(&config); |
| 242 } |
| 243 |
| 244 virtual void TearDown() { |
| 245 // Call Stop() to shut down internal threads. |
| 246 demuxer_->Stop(); |
| 247 } |
| 248 |
| 249 // Fixture members. |
| 250 scoped_refptr<FilterFactory> factory_; |
| 251 scoped_refptr<Demuxer> demuxer_; |
| 252 scoped_ptr<MockPipeline> pipeline_; |
| 253 scoped_ptr< MockFilterHost<Demuxer> > filter_host_; |
| 254 scoped_refptr<MockDataSource> data_source_; |
| 255 |
| 256 private: |
| 257 static void InitializeFFmpegMocks() { |
| 258 // Initialize function return codes. |
| 259 g_av_open_input_file = 0; |
| 260 g_av_find_stream_info = 0; |
| 261 g_av_read_frame = 0; |
| 262 |
| 263 // Initialize AVFormatContext structure. |
| 264 memset(&g_format, 0, sizeof(g_format)); |
| 265 |
| 266 // Initialize AVStream structures. |
| 267 for (size_t i = 0; i < kMaxStreams; ++i) { |
| 268 memset(&g_streams[i], 0, sizeof(g_streams[i])); |
| 269 g_streams[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond; |
| 270 g_streams[i].time_base.num = 1; |
| 271 } |
| 272 |
| 273 // Initialize AVCodexContext structures. |
| 274 memset(&g_audio_codec, 0, sizeof(g_audio_codec)); |
| 275 g_audio_codec.codec_type = CODEC_TYPE_AUDIO; |
| 276 g_audio_codec.codec_id = CODEC_ID_VORBIS; |
| 277 g_audio_codec.channels = 2; |
| 278 g_audio_codec.sample_rate = 44100; |
| 279 |
| 280 memset(&g_video_codec, 0, sizeof(g_video_codec)); |
| 281 g_video_codec.codec_type = CODEC_TYPE_VIDEO; |
| 282 g_video_codec.codec_id = CODEC_ID_THEORA; |
| 283 g_video_codec.height = 720; |
| 284 g_video_codec.width = 1280; |
| 285 |
| 286 memset(&g_data_codec, 0, sizeof(g_data_codec)); |
| 287 g_data_codec.codec_type = CODEC_TYPE_DATA; |
| 288 g_data_codec.codec_id = CODEC_ID_NONE; |
| 289 } |
| 290 |
| 291 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
| 292 }; |
| 293 |
253 } // namespace | 294 } // namespace |
254 | 295 |
255 // TODO(scherkus): http://crbug.com/10863 | 296 TEST(FFmpegDemuxerFactoryTest, Create) { |
256 TEST(FFmpegDemuxerTest, DISABLED_InitializeFailure) { | 297 // Should only accept application/octet-stream type. |
257 InitializeFFmpegMocks(); | |
258 | |
259 // Get FFmpegDemuxer's filter factory. | |
260 scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory(); | 298 scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory(); |
261 | |
262 // Should only accept application/octet-stream type. | |
263 MediaFormat media_format; | 299 MediaFormat media_format; |
264 media_format.SetAsString(MediaFormat::kMimeType, "foo/x-bar"); | 300 media_format.SetAsString(MediaFormat::kMimeType, "foo/x-bar"); |
265 scoped_refptr<Demuxer> demuxer(factory->Create<Demuxer>(media_format)); | 301 scoped_refptr<Demuxer> demuxer(factory->Create<Demuxer>(media_format)); |
266 ASSERT_FALSE(demuxer); | 302 ASSERT_FALSE(demuxer); |
| 303 |
| 304 // Try again with application/octet-stream mime type. |
267 media_format.Clear(); | 305 media_format.Clear(); |
268 media_format.SetAsString(MediaFormat::kMimeType, | 306 media_format.SetAsString(MediaFormat::kMimeType, |
269 mime_type::kApplicationOctetStream); | 307 mime_type::kApplicationOctetStream); |
270 demuxer = factory->Create<Demuxer>(media_format); | 308 demuxer = factory->Create<Demuxer>(media_format); |
271 ASSERT_TRUE(demuxer); | 309 ASSERT_TRUE(demuxer); |
| 310 } |
272 | 311 |
273 // Prepare a filter host and data source for the demuxer. | 312 TEST_F(FFmpegDemuxerTest, InitializeCouldNotOpen) { |
274 MockPipeline pipeline; | |
275 scoped_ptr< MockFilterHost<Demuxer> > filter_host; | |
276 filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer)); | |
277 MockFilterConfig config; | |
278 scoped_refptr<MockDataSource> data_source(new MockDataSource(&config)); | |
279 | |
280 // Simulate av_open_input_fail failing. | 313 // Simulate av_open_input_fail failing. |
281 g_av_open_input_file = AVERROR_IO; | 314 g_av_open_input_file = AVERROR_IO; |
282 g_av_find_stream_info = 0; | 315 g_av_find_stream_info = 0; |
283 EXPECT_TRUE(demuxer->Initialize(data_source)); | 316 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
284 EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_COULD_NOT_OPEN)); | 317 EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_COULD_NOT_OPEN)); |
285 EXPECT_FALSE(filter_host->IsInitialized()); | 318 EXPECT_FALSE(filter_host_->IsInitialized()); |
| 319 } |
286 | 320 |
| 321 TEST_F(FFmpegDemuxerTest, InitializeCouldNotParse) { |
287 // Simulate av_find_stream_info failing. | 322 // Simulate av_find_stream_info failing. |
288 g_av_open_input_file = 0; | 323 g_av_open_input_file = 0; |
289 g_av_find_stream_info = AVERROR_IO; | 324 g_av_find_stream_info = AVERROR_IO; |
290 pipeline.Reset(false); | |
291 demuxer = factory->Create<Demuxer>(media_format); | |
292 filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer)); | |
293 EXPECT_TRUE(demuxer->Initialize(data_source)); | |
294 EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_COULD_NOT_PARSE)); | |
295 EXPECT_FALSE(filter_host->IsInitialized()); | |
296 | 325 |
| 326 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
| 327 EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_COULD_NOT_PARSE)); |
| 328 EXPECT_FALSE(filter_host_->IsInitialized()); |
| 329 } |
| 330 |
| 331 TEST_F(FFmpegDemuxerTest, InitializeNoStreams) { |
297 // Simulate media with no parseable streams. | 332 // Simulate media with no parseable streams. |
298 InitializeFFmpegMocks(); | 333 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
299 pipeline.Reset(false); | 334 EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
300 demuxer = factory->Create<Demuxer>(media_format); | 335 EXPECT_FALSE(filter_host_->IsInitialized()); |
301 filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer)); | 336 } |
302 EXPECT_TRUE(demuxer->Initialize(data_source)); | |
303 EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | |
304 EXPECT_FALSE(filter_host->IsInitialized()); | |
305 | 337 |
| 338 TEST_F(FFmpegDemuxerTest, InitializeDataStreamOnly) { |
306 // Simulate media with a data stream but no audio or video streams. | 339 // Simulate media with a data stream but no audio or video streams. |
307 g_format.nb_streams = 1; | 340 g_format.nb_streams = 1; |
308 g_format.streams[0] = &g_streams[0]; | 341 g_format.streams[0] = &g_streams[0]; |
309 g_streams[0].codec = &g_data_codec; | 342 g_streams[0].codec = &g_data_codec; |
310 g_streams[0].duration = 10; | 343 g_streams[0].duration = 10; |
311 pipeline.Reset(false); | 344 |
312 demuxer = factory->Create<Demuxer>(media_format); | 345 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
313 filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer)); | 346 EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
314 EXPECT_TRUE(demuxer->Initialize(data_source)); | 347 EXPECT_FALSE(filter_host_->IsInitialized()); |
315 EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | |
316 EXPECT_FALSE(filter_host->IsInitialized()); | |
317 } | 348 } |
318 | 349 |
319 // TODO(scherkus): http://crbug.com/10863 | 350 TEST_F(FFmpegDemuxerTest, InitializeStreams) { |
320 TEST(FFmpegDemuxerTest, DISABLED_InitializeStreams) { | |
321 // Simulate media with a data stream, a video stream and audio stream. | 351 // Simulate media with a data stream, a video stream and audio stream. |
322 InitializeFFmpegMocks(); | |
323 g_format.nb_streams = 3; | 352 g_format.nb_streams = 3; |
324 g_format.streams[0] = &g_streams[0]; | 353 g_format.streams[0] = &g_streams[0]; |
325 g_format.streams[1] = &g_streams[1]; | 354 g_format.streams[1] = &g_streams[1]; |
326 g_format.streams[2] = &g_streams[2]; | 355 g_format.streams[2] = &g_streams[2]; |
327 g_streams[0].duration = 1000; | 356 g_streams[0].duration = 1000; |
328 g_streams[0].codec = &g_data_codec; | 357 g_streams[0].codec = &g_data_codec; |
329 g_streams[1].duration = 100; | 358 g_streams[1].duration = 100; |
330 g_streams[1].codec = &g_video_codec; | 359 g_streams[1].codec = &g_video_codec; |
331 g_streams[2].duration = 10; | 360 g_streams[2].duration = 10; |
332 g_streams[2].codec = &g_audio_codec; | 361 g_streams[2].codec = &g_audio_codec; |
333 | 362 |
334 // Create our pipeline. | 363 // Initialize the demuxer. |
335 MockPipeline pipeline; | 364 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
336 | 365 EXPECT_TRUE(filter_host_->WaitForInitialized()); |
337 // Create our data source. | 366 EXPECT_TRUE(filter_host_->IsInitialized()); |
338 MockFilterConfig config; | 367 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); |
339 scoped_refptr<MockDataSource> data_source = new MockDataSource(&config); | |
340 MockFilterHost<DataSource> filter_host_a(&pipeline, data_source); | |
341 EXPECT_TRUE(data_source->Initialize("foo")); | |
342 EXPECT_TRUE(filter_host_a.IsInitialized()); | |
343 | |
344 // Create our demuxer. | |
345 scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory(); | |
346 scoped_refptr<Demuxer> demuxer | |
347 = factory->Create<Demuxer>(data_source->media_format()); | |
348 EXPECT_TRUE(demuxer); | |
349 MockFilterHost<Demuxer> filter_host_b(&pipeline, demuxer); | |
350 EXPECT_TRUE(demuxer->Initialize(data_source)); | |
351 EXPECT_TRUE(filter_host_b.WaitForInitialized()); | |
352 EXPECT_TRUE(filter_host_b.IsInitialized()); | |
353 EXPECT_EQ(PIPELINE_OK, pipeline.GetError()); | |
354 | 368 |
355 // Since we ignore data streams, the duration should be equal to the video | 369 // Since we ignore data streams, the duration should be equal to the video |
356 // stream's duration. | 370 // stream's duration. |
357 EXPECT_EQ(g_streams[1].duration, pipeline.GetDuration().InMicroseconds()); | 371 EXPECT_EQ(g_streams[1].duration, pipeline_->GetDuration().InMicroseconds()); |
358 | 372 |
359 // Verify that 2 out of 3 streams were created. | 373 // Verify that 2 out of 3 streams were created. |
360 EXPECT_EQ(2, demuxer->GetNumberOfStreams()); | 374 EXPECT_EQ(2, demuxer_->GetNumberOfStreams()); |
361 | 375 |
362 // First stream should be video and support FFmpegDemuxerStream interface. | 376 // First stream should be video and support FFmpegDemuxerStream interface. |
363 scoped_refptr<DemuxerStream> stream = demuxer->GetStream(0); | 377 scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(0); |
364 scoped_refptr<FFmpegDemuxerStream> ffmpeg_demuxer_stream; | 378 scoped_refptr<FFmpegDemuxerStream> ffmpeg_demuxer_stream; |
365 ASSERT_TRUE(stream); | 379 ASSERT_TRUE(stream); |
366 std::string mime_type; | 380 std::string mime_type; |
367 EXPECT_TRUE( | 381 EXPECT_TRUE( |
368 stream->media_format().GetAsString(MediaFormat::kMimeType, &mime_type)); | 382 stream->media_format().GetAsString(MediaFormat::kMimeType, &mime_type)); |
369 EXPECT_STREQ(mime_type::kFFmpegVideo, mime_type.c_str()); | 383 EXPECT_STREQ(mime_type::kFFmpegVideo, mime_type.c_str()); |
370 EXPECT_TRUE(stream->QueryInterface(&ffmpeg_demuxer_stream)); | 384 EXPECT_TRUE(stream->QueryInterface(&ffmpeg_demuxer_stream)); |
371 EXPECT_TRUE(ffmpeg_demuxer_stream); | 385 EXPECT_TRUE(ffmpeg_demuxer_stream); |
372 EXPECT_EQ(&g_streams[1], ffmpeg_demuxer_stream->av_stream()); | 386 EXPECT_EQ(&g_streams[1], ffmpeg_demuxer_stream->av_stream()); |
373 | 387 |
374 // Second stream should be audio and support FFmpegDemuxerStream interface. | 388 // Second stream should be audio and support FFmpegDemuxerStream interface. |
375 stream = demuxer->GetStream(1); | 389 stream = demuxer_->GetStream(1); |
376 ffmpeg_demuxer_stream = NULL; | 390 ffmpeg_demuxer_stream = NULL; |
377 ASSERT_TRUE(stream); | 391 ASSERT_TRUE(stream); |
378 EXPECT_TRUE( | 392 EXPECT_TRUE(stream->media_format().GetAsString(MediaFormat::kMimeType, |
379 stream->media_format().GetAsString(MediaFormat::kMimeType, &mime_type)); | 393 &mime_type)); |
380 EXPECT_STREQ(mime_type::kFFmpegAudio, mime_type.c_str()); | 394 EXPECT_STREQ(mime_type::kFFmpegAudio, mime_type.c_str()); |
381 EXPECT_TRUE(stream->QueryInterface(&ffmpeg_demuxer_stream)); | 395 EXPECT_TRUE(stream->QueryInterface(&ffmpeg_demuxer_stream)); |
382 EXPECT_TRUE(ffmpeg_demuxer_stream); | 396 EXPECT_TRUE(ffmpeg_demuxer_stream); |
383 EXPECT_EQ(&g_streams[2], ffmpeg_demuxer_stream->av_stream()); | 397 EXPECT_EQ(&g_streams[2], ffmpeg_demuxer_stream->av_stream()); |
384 } | 398 } |
385 | 399 |
386 // TODO(scherkus): as we keep refactoring and improving our mocks (both FFmpeg | 400 TEST_F(FFmpegDemuxerTest, ReadAndSeek) { |
387 // and pipeline/filters), try to break this test into two. Big issue right now | |
388 // is that it takes ~50 lines of code just to set up FFmpegDemuxer. | |
389 // | |
390 // TODO(scherkus): http://crbug.com/10863 | |
391 TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) { | |
392 // Prepare some test data. | 401 // Prepare some test data. |
393 const int kPacketData = 0; | 402 const int kPacketData = 0; |
394 const int kPacketAudio = 1; | 403 const int kPacketAudio = 1; |
395 const int kPacketVideo = 2; | 404 const int kPacketVideo = 2; |
396 const int kAudio = 0; | 405 const int kAudio = 0; |
397 const int kVideo = 1; | 406 const int kVideo = 1; |
398 const size_t kDataSize = 4; | 407 const size_t kDataSize = 4; |
399 uint8 audio_data[kDataSize] = {0, 1, 2, 3}; | 408 uint8 audio_data[kDataSize] = {0, 1, 2, 3}; |
400 uint8 video_data[kDataSize] = {4, 5, 6, 7}; | 409 uint8 video_data[kDataSize] = {4, 5, 6, 7}; |
401 | 410 |
402 // Simulate media with a data stream, audio stream and video stream. Having | 411 // Simulate media with a data stream, audio stream and video stream. Having |
403 // the data stream first forces the audio and video streams to get remapped | 412 // the data stream first forces the audio and video streams to get remapped |
404 // from indices {1,2} to {0,1} respectively, which covers an important test | 413 // from indices {1,2} to {0,1} respectively, which covers an important test |
405 // case. | 414 // case. |
406 InitializeFFmpegMocks(); | |
407 g_format.nb_streams = 3; | 415 g_format.nb_streams = 3; |
408 g_format.streams[kPacketData] = &g_streams[0]; | 416 g_format.streams[kPacketData] = &g_streams[0]; |
409 g_format.streams[kPacketAudio] = &g_streams[1]; | 417 g_format.streams[kPacketAudio] = &g_streams[1]; |
410 g_format.streams[kPacketVideo] = &g_streams[2]; | 418 g_format.streams[kPacketVideo] = &g_streams[2]; |
411 g_streams[0].duration = 10; | 419 g_streams[0].duration = 10; |
412 g_streams[0].codec = &g_data_codec; | 420 g_streams[0].codec = &g_data_codec; |
413 g_streams[1].duration = 10; | 421 g_streams[1].duration = 10; |
414 g_streams[1].codec = &g_audio_codec; | 422 g_streams[1].codec = &g_audio_codec; |
415 g_streams[2].duration = 10; | 423 g_streams[2].duration = 10; |
416 g_streams[2].codec = &g_video_codec; | 424 g_streams[2].codec = &g_video_codec; |
417 | 425 |
418 // Create our pipeline. | 426 // Initialize the demuxer. |
419 MockPipeline pipeline; | 427 EXPECT_TRUE(demuxer_->Initialize(data_source_.get())); |
420 | 428 EXPECT_TRUE(filter_host_->WaitForInitialized()); |
421 // Create our data source. | 429 EXPECT_TRUE(filter_host_->IsInitialized()); |
422 MockFilterConfig config; | 430 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); |
423 scoped_refptr<MockDataSource> data_source = new MockDataSource(&config); | |
424 MockFilterHost<DataSource> filter_host_a(&pipeline, data_source); | |
425 EXPECT_TRUE(data_source->Initialize("foo")); | |
426 EXPECT_TRUE(filter_host_a.IsInitialized()); | |
427 | |
428 // Create our demuxer. | |
429 scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory(); | |
430 scoped_refptr<Demuxer> demuxer | |
431 = factory->Create<Demuxer>(data_source->media_format()); | |
432 EXPECT_TRUE(demuxer); | |
433 MockFilterHost<Demuxer> filter_host_b(&pipeline, demuxer); | |
434 EXPECT_TRUE(demuxer->Initialize(data_source)); | |
435 EXPECT_TRUE(filter_host_b.WaitForInitialized()); | |
436 EXPECT_TRUE(filter_host_b.IsInitialized()); | |
437 EXPECT_EQ(PIPELINE_OK, pipeline.GetError()); | |
438 | 431 |
439 // Verify both streams were created. | 432 // Verify both streams were created. |
440 EXPECT_EQ(2, demuxer->GetNumberOfStreams()); | 433 EXPECT_EQ(2, demuxer_->GetNumberOfStreams()); |
441 | 434 |
442 // Get our streams. | 435 // Get our streams. |
443 scoped_refptr<DemuxerStream> audio_stream = demuxer->GetStream(kAudio); | 436 scoped_refptr<DemuxerStream> audio_stream = demuxer_->GetStream(kAudio); |
444 scoped_refptr<DemuxerStream> video_stream = demuxer->GetStream(kVideo); | 437 scoped_refptr<DemuxerStream> video_stream = demuxer_->GetStream(kVideo); |
445 ASSERT_TRUE(audio_stream); | 438 ASSERT_TRUE(audio_stream); |
446 ASSERT_TRUE(video_stream); | 439 ASSERT_TRUE(video_stream); |
447 | 440 |
448 // Prepare data packets, which should all get immediately released. | 441 // Prepare data packets, which should all get immediately released. |
449 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); | 442 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); |
450 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); | 443 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); |
451 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); | 444 PacketQueue::get()->Enqueue(kPacketData, kDataSize, audio_data); |
452 | 445 |
453 // Prepare our test audio packet. | 446 // Prepare our test audio packet. |
454 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 447 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
455 | 448 |
456 // Attempt a read from the audio stream and run the message loop until done. | 449 // Attempt a read from the audio stream and run the message loop until done. |
457 scoped_refptr<TestReader> reader(new TestReader()); | 450 scoped_refptr<TestReader> reader(new TestReader()); |
458 reader->Read(audio_stream); | 451 reader->Read(audio_stream); |
459 pipeline.RunAllTasks(); | 452 pipeline_->RunAllTasks(); |
460 EXPECT_TRUE(reader->WaitForRead()); | 453 EXPECT_TRUE(reader->WaitForRead()); |
461 EXPECT_TRUE(reader->called()); | 454 EXPECT_TRUE(reader->called()); |
462 ASSERT_TRUE(reader->buffer()); | 455 ASSERT_TRUE(reader->buffer()); |
463 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 456 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
464 EXPECT_EQ(audio_data, reader->buffer()->GetData()); | 457 EXPECT_EQ(audio_data, reader->buffer()->GetData()); |
465 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 458 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
466 | 459 |
467 // Prepare our test video packet. | 460 // Prepare our test video packet. |
468 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); | 461 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); |
469 | 462 |
470 // Attempt a read from the video stream and run the message loop until done. | 463 // Attempt a read from the video stream and run the message loop until done. |
471 reader->Reset(); | 464 reader->Reset(); |
472 reader->Read(video_stream); | 465 reader->Read(video_stream); |
473 pipeline.RunAllTasks(); | 466 pipeline_->RunAllTasks(); |
474 EXPECT_TRUE(reader->WaitForRead()); | 467 EXPECT_TRUE(reader->WaitForRead()); |
475 EXPECT_TRUE(reader->called()); | 468 EXPECT_TRUE(reader->called()); |
476 ASSERT_TRUE(reader->buffer()); | 469 ASSERT_TRUE(reader->buffer()); |
477 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 470 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
478 EXPECT_EQ(video_data, reader->buffer()->GetData()); | 471 EXPECT_EQ(video_data, reader->buffer()->GetData()); |
479 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 472 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
480 | 473 |
481 // Manually release buffer, which should release any remaining AVPackets. | 474 // Manually release buffer, which should release any remaining AVPackets. |
482 reader = NULL; | 475 reader = NULL; |
483 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); | 476 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); |
484 | 477 |
485 //---------------------------------------------------------------------------- | 478 //---------------------------------------------------------------------------- |
486 // Seek tests. | 479 // Seek tests. |
487 EXPECT_FALSE(g_seek_event); | 480 EXPECT_FALSE(g_seek_event); |
488 g_seek_event = new base::WaitableEvent(false, false); | 481 g_seek_event = new base::WaitableEvent(false, false); |
489 | 482 |
490 // Let's trigger a simple forward seek with no outstanding packets. | 483 // Let's trigger a simple forward seek with no outstanding packets. |
491 g_expected_seek_timestamp = 1234; | 484 g_expected_seek_timestamp = 1234; |
492 g_expected_seek_flags = 0; | 485 g_expected_seek_flags = 0; |
493 demuxer->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp)); | 486 demuxer_->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp)); |
494 EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1))); | 487 EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1))); |
495 | 488 |
496 // The next read from each stream should now be discontinuous, but subsequent | 489 // The next read from each stream should now be discontinuous, but subsequent |
497 // reads should not. | 490 // reads should not. |
498 | 491 |
499 // Prepare our test audio packet. | 492 // Prepare our test audio packet. |
500 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 493 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
501 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 494 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
502 | 495 |
503 // Audio read #1, should be discontinuous. | 496 // Audio read #1, should be discontinuous. |
504 reader = new TestReader(); | 497 reader = new TestReader(); |
505 reader->Read(audio_stream); | 498 reader->Read(audio_stream); |
506 pipeline.RunAllTasks(); | 499 pipeline_->RunAllTasks(); |
507 EXPECT_TRUE(reader->WaitForRead()); | 500 EXPECT_TRUE(reader->WaitForRead()); |
508 EXPECT_TRUE(reader->called()); | 501 EXPECT_TRUE(reader->called()); |
509 ASSERT_TRUE(reader->buffer()); | 502 ASSERT_TRUE(reader->buffer()); |
510 EXPECT_TRUE(reader->buffer()->IsDiscontinuous()); | 503 EXPECT_TRUE(reader->buffer()->IsDiscontinuous()); |
511 EXPECT_EQ(audio_data, reader->buffer()->GetData()); | 504 EXPECT_EQ(audio_data, reader->buffer()->GetData()); |
512 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 505 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
513 | 506 |
514 // Audio read #2, should not be discontinuous. | 507 // Audio read #2, should not be discontinuous. |
515 reader->Reset(); | 508 reader->Reset(); |
516 reader->Read(audio_stream); | 509 reader->Read(audio_stream); |
517 pipeline.RunAllTasks(); | 510 pipeline_->RunAllTasks(); |
518 EXPECT_TRUE(reader->WaitForRead()); | 511 EXPECT_TRUE(reader->WaitForRead()); |
519 EXPECT_TRUE(reader->called()); | 512 EXPECT_TRUE(reader->called()); |
520 ASSERT_TRUE(reader->buffer()); | 513 ASSERT_TRUE(reader->buffer()); |
521 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 514 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
522 EXPECT_EQ(audio_data, reader->buffer()->GetData()); | 515 EXPECT_EQ(audio_data, reader->buffer()->GetData()); |
523 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 516 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
524 | 517 |
525 // Prepare our test video packet. | 518 // Prepare our test video packet. |
526 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); | 519 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); |
527 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); | 520 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); |
528 | 521 |
529 // Video read #1, should be discontinuous. | 522 // Video read #1, should be discontinuous. |
530 reader->Reset(); | 523 reader->Reset(); |
531 reader->Read(video_stream); | 524 reader->Read(video_stream); |
532 pipeline.RunAllTasks(); | 525 pipeline_->RunAllTasks(); |
533 EXPECT_TRUE(reader->WaitForRead()); | 526 EXPECT_TRUE(reader->WaitForRead()); |
534 EXPECT_TRUE(reader->called()); | 527 EXPECT_TRUE(reader->called()); |
535 ASSERT_TRUE(reader->buffer()); | 528 ASSERT_TRUE(reader->buffer()); |
536 EXPECT_TRUE(reader->buffer()->IsDiscontinuous()); | 529 EXPECT_TRUE(reader->buffer()->IsDiscontinuous()); |
537 EXPECT_EQ(video_data, reader->buffer()->GetData()); | 530 EXPECT_EQ(video_data, reader->buffer()->GetData()); |
538 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 531 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
539 | 532 |
540 // Video read #2, should not be discontinuous. | 533 // Video read #2, should not be discontinuous. |
541 reader->Reset(); | 534 reader->Reset(); |
542 reader->Read(video_stream); | 535 reader->Read(video_stream); |
543 pipeline.RunAllTasks(); | 536 pipeline_->RunAllTasks(); |
544 EXPECT_TRUE(reader->WaitForRead()); | 537 EXPECT_TRUE(reader->WaitForRead()); |
545 EXPECT_TRUE(reader->called()); | 538 EXPECT_TRUE(reader->called()); |
546 ASSERT_TRUE(reader->buffer()); | 539 ASSERT_TRUE(reader->buffer()); |
547 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 540 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
548 EXPECT_EQ(video_data, reader->buffer()->GetData()); | 541 EXPECT_EQ(video_data, reader->buffer()->GetData()); |
549 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 542 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
550 | 543 |
551 // Manually release buffer, which should release any remaining AVPackets. | 544 // Manually release buffer, which should release any remaining AVPackets. |
552 reader = NULL; | 545 reader = NULL; |
553 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); | 546 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); |
554 | 547 |
555 // Let's trigger another simple forward seek, but with outstanding packets. | 548 // Let's trigger another simple forward seek, but with outstanding packets. |
556 // The outstanding packets should get freed after the Seek() is issued. | 549 // The outstanding packets should get freed after the Seek() is issued. |
557 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 550 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
558 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 551 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
559 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); | 552 PacketQueue::get()->Enqueue(kPacketAudio, kDataSize, audio_data); |
560 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); | 553 PacketQueue::get()->Enqueue(kPacketVideo, kDataSize, video_data); |
561 | 554 |
562 // Attempt a read from video stream, which will force the demuxer to queue | 555 // Attempt a read from video stream, which will force the demuxer to queue |
563 // the audio packets preceding the video packet. | 556 // the audio packets preceding the video packet. |
564 reader = new TestReader(); | 557 reader = new TestReader(); |
565 reader->Read(video_stream); | 558 reader->Read(video_stream); |
566 pipeline.RunAllTasks(); | 559 pipeline_->RunAllTasks(); |
567 EXPECT_TRUE(reader->WaitForRead()); | 560 EXPECT_TRUE(reader->WaitForRead()); |
568 EXPECT_TRUE(reader->called()); | 561 EXPECT_TRUE(reader->called()); |
569 ASSERT_TRUE(reader->buffer()); | 562 ASSERT_TRUE(reader->buffer()); |
570 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); | 563 EXPECT_FALSE(reader->buffer()->IsDiscontinuous()); |
571 EXPECT_EQ(video_data, reader->buffer()->GetData()); | 564 EXPECT_EQ(video_data, reader->buffer()->GetData()); |
572 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); | 565 EXPECT_EQ(kDataSize, reader->buffer()->GetDataSize()); |
573 | 566 |
574 // Manually release video buffer, remaining audio packets are outstanding. | 567 // Manually release video buffer, remaining audio packets are outstanding. |
575 reader = NULL; | 568 reader = NULL; |
576 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(3)); | 569 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(3)); |
577 | 570 |
578 // Trigger the seek. | 571 // Trigger the seek. |
579 g_expected_seek_timestamp = 1234; | 572 g_expected_seek_timestamp = 1234; |
580 g_expected_seek_flags = 0; | 573 g_expected_seek_flags = 0; |
581 demuxer->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp)); | 574 demuxer_->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp)); |
582 EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1))); | 575 EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1))); |
583 | 576 |
584 // All outstanding packets should have been freed. | 577 // All outstanding packets should have been freed. |
585 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); | 578 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); |
586 | 579 |
587 // Clean up. | 580 // Clean up. |
588 delete g_seek_event; | 581 delete g_seek_event; |
589 g_seek_event = NULL; | 582 g_seek_event = NULL; |
590 | 583 |
591 //---------------------------------------------------------------------------- | 584 //---------------------------------------------------------------------------- |
592 // End of stream tests. | 585 // End of stream tests. |
593 | 586 |
594 // Simulate end of stream. | 587 // Simulate end of stream. |
595 g_av_read_frame = AVERROR_IO; | 588 g_av_read_frame = AVERROR_IO; |
596 | 589 |
597 // Attempt a read from the audio stream and run the message loop until done. | 590 // Attempt a read from the audio stream and run the message loop until done. |
598 reader = new TestReader(); | 591 reader = new TestReader(); |
599 reader->Read(audio_stream); | 592 reader->Read(audio_stream); |
600 pipeline.RunAllTasks(); | 593 pipeline_->RunAllTasks(); |
601 EXPECT_FALSE(reader->WaitForRead()); | 594 EXPECT_FALSE(reader->WaitForRead()); |
602 EXPECT_FALSE(reader->called()); | 595 EXPECT_FALSE(reader->called()); |
603 EXPECT_FALSE(reader->buffer()); | 596 EXPECT_FALSE(reader->buffer()); |
604 | 597 |
605 // Manually release buffer, which should release any remaining AVPackets. | 598 // Manually release buffer, which should release any remaining AVPackets. |
606 reader = NULL; | 599 reader = NULL; |
607 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); | 600 EXPECT_TRUE(PacketQueue::get()->WaitForOutstandingPackets(0)); |
608 } | 601 } |
OLD | NEW |