OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/filters/chunk_demuxer.h" | 5 #include "media/filters/chunk_demuxer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at | 78 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at |
79 // index 1 and spans 8 bytes. | 79 // index 1 and spans 8 bytes. |
80 const int kVideoTrackSizeOffset = 1; | 80 const int kVideoTrackSizeOffset = 1; |
81 const int kVideoTrackSizeWidth = 8; | 81 const int kVideoTrackSizeWidth = 8; |
82 const int kVideoTrackEntryHeaderSize = | 82 const int kVideoTrackEntryHeaderSize = |
83 kVideoTrackSizeOffset + kVideoTrackSizeWidth; | 83 kVideoTrackSizeOffset + kVideoTrackSizeWidth; |
84 | 84 |
85 const int kVideoTrackNum = 1; | 85 const int kVideoTrackNum = 1; |
86 const int kAudioTrackNum = 2; | 86 const int kAudioTrackNum = 2; |
87 const int kTextTrackNum = 3; | 87 const int kTextTrackNum = 3; |
88 const int kAlternateTextTrackNum = 4; | 88 const int kAlternateVideoTrackNum = 4; |
89 const int kAlternateAudioTrackNum = 5; | |
90 const int kAlternateTextTrackNum = 6; | |
89 | 91 |
90 const int kAudioBlockDuration = 23; | 92 const int kAudioBlockDuration = 23; |
91 const int kVideoBlockDuration = 33; | 93 const int kVideoBlockDuration = 33; |
92 const int kTextBlockDuration = 100; | 94 const int kTextBlockDuration = 100; |
93 const int kBlockSize = 10; | 95 const int kBlockSize = 10; |
94 | 96 |
95 const char kSourceId[] = "SourceId"; | 97 const char kSourceId[] = "SourceId"; |
96 const char kDefaultFirstClusterRange[] = "{ [0,46) }"; | 98 const char kDefaultFirstClusterRange[] = "{ [0,46) }"; |
97 const int kDefaultFirstClusterEndTimestamp = 66; | 99 const int kDefaultFirstClusterEndTimestamp = 66; |
98 const int kDefaultSecondClusterEndTimestamp = 132; | 100 const int kDefaultSecondClusterEndTimestamp = 132; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 // in kDefaultFirstCluster() so that these two clusters represent | 260 // in kDefaultFirstCluster() so that these two clusters represent |
259 // a continuous region. | 261 // a continuous region. |
260 scoped_ptr<Cluster> kDefaultSecondCluster() { | 262 scoped_ptr<Cluster> kDefaultSecondCluster() { |
261 return GenerateCluster(46, 66, 5); | 263 return GenerateCluster(46, 66, 5); |
262 } | 264 } |
263 | 265 |
264 ChunkDemuxerTest() | 266 ChunkDemuxerTest() |
265 : media_log_(new StrictMock<MockMediaLog>()), | 267 : media_log_(new StrictMock<MockMediaLog>()), |
266 append_window_end_for_next_append_(kInfiniteDuration()) { | 268 append_window_end_for_next_append_(kInfiniteDuration()) { |
267 init_segment_received_cb_ = base::Bind( | 269 init_segment_received_cb_ = base::Bind( |
268 &ChunkDemuxerTest::InitSegmentReceivedWrapper, base::Unretained(this)); | 270 &ChunkDemuxerTest::InitSegmentReceived, base::Unretained(this)); |
269 CreateNewDemuxer(); | 271 CreateNewDemuxer(); |
270 } | 272 } |
271 | 273 |
272 void CreateNewDemuxer() { | 274 void CreateNewDemuxer() { |
273 base::Closure open_cb = | 275 base::Closure open_cb = |
274 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); | 276 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
275 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( | 277 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( |
276 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); | 278 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); |
277 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, | 279 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, |
278 media_log_, true)); | 280 media_log_, true)); |
279 } | 281 } |
280 | 282 |
281 virtual ~ChunkDemuxerTest() { | 283 virtual ~ChunkDemuxerTest() { |
282 ShutdownDemuxer(); | 284 ShutdownDemuxer(); |
283 } | 285 } |
284 | 286 |
285 void CreateInitSegment(int stream_flags, | 287 void CreateInitSegment(int stream_flags, |
286 bool is_audio_encrypted, | |
287 bool is_video_encrypted, | |
288 scoped_ptr<uint8_t[]>* buffer, | |
289 int* size) { | |
290 CreateInitSegmentInternal( | |
291 stream_flags, is_audio_encrypted, is_video_encrypted, buffer, false, | |
292 size); | |
293 } | |
294 | |
295 void CreateInitSegmentWithAlternateTextTrackNum(int stream_flags, | |
296 bool is_audio_encrypted, | |
297 bool is_video_encrypted, | |
298 scoped_ptr<uint8_t[]>* buffer, | |
299 int* size) { | |
300 DCHECK(stream_flags & HAS_TEXT); | |
301 CreateInitSegmentInternal( | |
302 stream_flags, is_audio_encrypted, is_video_encrypted, buffer, true, | |
303 size); | |
304 } | |
305 | |
306 void CreateInitSegmentInternal(int stream_flags, | |
307 bool is_audio_encrypted, | 288 bool is_audio_encrypted, |
308 bool is_video_encrypted, | 289 bool is_video_encrypted, |
309 scoped_ptr<uint8_t[]>* buffer, | 290 scoped_ptr<uint8_t[]>* buffer, |
310 bool use_alternate_text_track_id, | |
311 int* size) { | 291 int* size) { |
312 bool has_audio = (stream_flags & HAS_AUDIO) != 0; | 292 bool has_audio = (stream_flags & HAS_AUDIO) != 0; |
313 bool has_video = (stream_flags & HAS_VIDEO) != 0; | 293 bool has_video = (stream_flags & HAS_VIDEO) != 0; |
314 bool has_text = (stream_flags & HAS_TEXT) != 0; | 294 bool has_text = (stream_flags & HAS_TEXT) != 0; |
315 scoped_refptr<DecoderBuffer> ebml_header; | 295 scoped_refptr<DecoderBuffer> ebml_header; |
316 scoped_refptr<DecoderBuffer> info; | 296 scoped_refptr<DecoderBuffer> info; |
317 scoped_refptr<DecoderBuffer> audio_track_entry; | 297 scoped_refptr<DecoderBuffer> audio_track_entry; |
318 scoped_refptr<DecoderBuffer> video_track_entry; | 298 scoped_refptr<DecoderBuffer> video_track_entry; |
319 scoped_refptr<DecoderBuffer> audio_content_encodings; | 299 scoped_refptr<DecoderBuffer> audio_content_encodings; |
320 scoped_refptr<DecoderBuffer> video_content_encodings; | 300 scoped_refptr<DecoderBuffer> video_content_encodings; |
321 scoped_refptr<DecoderBuffer> text_track_entry; | 301 scoped_refptr<DecoderBuffer> text_track_entry; |
322 | 302 |
323 ebml_header = ReadTestDataFile("webm_ebml_element"); | 303 ebml_header = ReadTestDataFile("webm_ebml_element"); |
324 | 304 |
325 info = ReadTestDataFile("webm_info_element"); | 305 info = ReadTestDataFile("webm_info_element"); |
326 | 306 |
327 int tracks_element_size = 0; | 307 int tracks_element_size = 0; |
328 | 308 |
329 if (has_audio) { | 309 if (has_audio) { |
330 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); | 310 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); |
331 tracks_element_size += audio_track_entry->data_size(); | 311 tracks_element_size += audio_track_entry->data_size(); |
312 // Verify that we have TrackNum (0xD7) EBML element at expected offset. | |
313 DCHECK_EQ(audio_track_entry->data()[9], 0xD7); | |
wolenetz
2016/04/08 22:41:49
nit: we have 0xD7 defined and usable from here: ht
servolk
2016/04/08 22:50:28
Done.
| |
314 // Ensure the track id in TrackNum EBML element matches kAudioTrackNum. | |
wolenetz
2016/04/08 22:41:49
nit: since we're DCHECKing the TrackNum, should we
servolk
2016/04/08 22:50:28
Done.
| |
315 DCHECK_EQ(audio_track_entry->data()[11], kAudioTrackNum); | |
316 if (stream_flags & USE_ALTERNATE_AUDIO_TRACK_ID) | |
317 audio_track_entry->writable_data()[11] = kAlternateAudioTrackNum; | |
332 if (is_audio_encrypted) { | 318 if (is_audio_encrypted) { |
333 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); | 319 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); |
334 tracks_element_size += audio_content_encodings->data_size(); | 320 tracks_element_size += audio_content_encodings->data_size(); |
335 } | 321 } |
336 } | 322 } |
337 | 323 |
338 if (has_video) { | 324 if (has_video) { |
339 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); | 325 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); |
340 tracks_element_size += video_track_entry->data_size(); | 326 tracks_element_size += video_track_entry->data_size(); |
327 // Verify that we have TrackNum (0xD7) EBML element at expected offset. | |
328 DCHECK_EQ(video_track_entry->data()[9], 0xD7); | |
wolenetz
2016/04/08 22:41:49
nit ditto re-use defined constant
servolk
2016/04/08 22:50:28
Done.
| |
329 // Ensure the track id in TrackNum EBML element matches kVideoTrackNum. | |
wolenetz
2016/04/08 22:41:49
nit ditto DCHECK track id size?
servolk
2016/04/08 22:50:28
Done.
| |
330 DCHECK_EQ(video_track_entry->data()[11], kVideoTrackNum); | |
331 if (stream_flags & USE_ALTERNATE_VIDEO_TRACK_ID) | |
332 video_track_entry->writable_data()[11] = kAlternateVideoTrackNum; | |
341 if (is_video_encrypted) { | 333 if (is_video_encrypted) { |
342 video_content_encodings = ReadTestDataFile("webm_content_encodings"); | 334 video_content_encodings = ReadTestDataFile("webm_content_encodings"); |
343 tracks_element_size += video_content_encodings->data_size(); | 335 tracks_element_size += video_content_encodings->data_size(); |
344 } | 336 } |
345 } | 337 } |
346 | 338 |
347 if (has_text) { | 339 if (has_text) { |
348 // TODO(matthewjheaney): create an abstraction to do | 340 // TODO(matthewjheaney): create an abstraction to do |
349 // this (http://crbug/321454). | 341 // this (http://crbug/321454). |
350 // We need it to also handle the creation of multiple text tracks. | 342 // We need it to also handle the creation of multiple text tracks. |
351 // | 343 // |
352 // This is the track entry for a text track, | 344 // This is the track entry for a text track, |
353 // TrackEntry [AE], size=30 | 345 // TrackEntry [AE], size=30 |
354 // TrackNum [D7], size=1, val=3 (or 4 if use_alternate_text_track_id) | 346 // TrackNum [D7], size=1, val=3 (or 4 if USE_ALTERNATE_TEXT_TRACK_ID) |
355 // TrackUID [73] [C5], size=1, value=3 (must remain constant for same | 347 // TrackUID [73] [C5], size=1, value=3 (must remain constant for same |
356 // track, even if TrackNum changes) | 348 // track, even if TrackNum changes) |
357 // TrackType [83], size=1, val=0x11 | 349 // TrackType [83], size=1, val=0x11 |
358 // CodecId [86], size=18, val="D_WEBVTT/SUBTITLES" | 350 // CodecId [86], size=18, val="D_WEBVTT/SUBTITLES" |
359 char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03" | 351 char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03" |
360 "\x83\x81\x11\x86\x92" | 352 "\x83\x81\x11\x86\x92" |
361 "D_WEBVTT/SUBTITLES"; | 353 "D_WEBVTT/SUBTITLES"; |
362 DCHECK_EQ(str[4], kTextTrackNum); | 354 DCHECK_EQ(str[4], kTextTrackNum); |
363 if (use_alternate_text_track_id) | 355 if (stream_flags & USE_ALTERNATE_TEXT_TRACK_ID) |
364 str[4] = kAlternateTextTrackNum; | 356 str[4] = kAlternateTextTrackNum; |
365 | 357 |
366 const int len = strlen(str); | 358 const int len = strlen(str); |
367 DCHECK_EQ(len, 32); | 359 DCHECK_EQ(len, 32); |
368 const uint8_t* const buf = reinterpret_cast<const uint8_t*>(str); | 360 const uint8_t* const buf = reinterpret_cast<const uint8_t*>(str); |
369 text_track_entry = DecoderBuffer::CopyFrom(buf, len); | 361 text_track_entry = DecoderBuffer::CopyFrom(buf, len); |
370 tracks_element_size += text_track_entry->data_size(); | 362 tracks_element_size += text_track_entry->data_size(); |
371 } | 363 } |
372 | 364 |
373 *size = ebml_header->data_size() + info->data_size() + | 365 *size = ebml_header->data_size() + info->data_size() + |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 type = "video/webm"; | 439 type = "video/webm"; |
448 } | 440 } |
449 | 441 |
450 if (!has_audio && !has_video) { | 442 if (!has_audio && !has_video) { |
451 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); | 443 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); |
452 } | 444 } |
453 | 445 |
454 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); | 446 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); |
455 if (status == ChunkDemuxer::kOk) | 447 if (status == ChunkDemuxer::kOk) |
456 demuxer_->SetTracksWatcher( | 448 demuxer_->SetTracksWatcher( |
457 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 449 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
458 base::Unretained(this))); | 450 base::Unretained(this))); |
459 return status; | 451 return status; |
460 } | 452 } |
461 | 453 |
462 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 454 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
463 ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) { | 455 ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) { |
464 std::vector<std::string> codecs; | 456 std::vector<std::string> codecs; |
465 std::string type = "video/mp2t"; | 457 std::string type = "video/mp2t"; |
466 codecs.push_back("mp4a.40.2"); | 458 codecs.push_back("mp4a.40.2"); |
467 codecs.push_back("avc1.640028"); | 459 codecs.push_back("avc1.640028"); |
468 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); | 460 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); |
469 if (status == ChunkDemuxer::kOk) | 461 if (status == ChunkDemuxer::kOk) |
470 demuxer_->SetTracksWatcher( | 462 demuxer_->SetTracksWatcher( |
471 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 463 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
472 base::Unretained(this))); | 464 base::Unretained(this))); |
473 return status; | 465 return status; |
474 } | 466 } |
475 #endif | 467 #endif |
476 | 468 |
477 void AppendData(const uint8_t* data, size_t length) { | 469 void AppendData(const uint8_t* data, size_t length) { |
478 AppendData(kSourceId, data, length); | 470 AppendData(kSourceId, data, length); |
479 } | 471 } |
480 | 472 |
481 void AppendCluster(const std::string& source_id, | 473 void AppendCluster(const std::string& source_id, |
482 scoped_ptr<Cluster> cluster) { | 474 scoped_ptr<Cluster> cluster) { |
483 AppendData(source_id, cluster->data(), cluster->size()); | 475 AppendData(source_id, cluster->data(), cluster->size()); |
484 } | 476 } |
485 | 477 |
486 void AppendCluster(scoped_ptr<Cluster> cluster) { | 478 void AppendCluster(scoped_ptr<Cluster> cluster) { |
487 AppendCluster(kSourceId, std::move(cluster)); | 479 AppendCluster(kSourceId, std::move(cluster)); |
488 } | 480 } |
489 | 481 |
490 void AppendCluster(int timecode, int block_count) { | 482 void AppendCluster(int timecode, int block_count) { |
491 AppendCluster(GenerateCluster(timecode, block_count)); | 483 AppendCluster(GenerateCluster(timecode, block_count)); |
492 } | 484 } |
493 | 485 |
494 void AppendSingleStreamCluster(const std::string& source_id, int track_number, | 486 void AppendSingleStreamCluster(const std::string& source_id, int track_number, |
495 int timecode, int block_count) { | 487 int timecode, int block_count) { |
496 int block_duration = 0; | 488 int block_duration = 0; |
497 switch (track_number) { | 489 switch (track_number) { |
498 case kVideoTrackNum: | 490 case kVideoTrackNum: |
491 case kAlternateVideoTrackNum: | |
499 block_duration = kVideoBlockDuration; | 492 block_duration = kVideoBlockDuration; |
500 break; | 493 break; |
501 case kAudioTrackNum: | 494 case kAudioTrackNum: |
495 case kAlternateAudioTrackNum: | |
502 block_duration = kAudioBlockDuration; | 496 block_duration = kAudioBlockDuration; |
503 break; | 497 break; |
504 case kTextTrackNum: // Fall-through. | 498 case kTextTrackNum: // Fall-through. |
505 case kAlternateTextTrackNum: | 499 case kAlternateTextTrackNum: |
506 block_duration = kTextBlockDuration; | 500 block_duration = kTextBlockDuration; |
507 break; | 501 break; |
508 } | 502 } |
509 ASSERT_NE(block_duration, 0); | 503 ASSERT_NE(block_duration, 0); |
510 int end_timecode = timecode + block_count * block_duration; | 504 int end_timecode = timecode + block_count * block_duration; |
511 AppendCluster(source_id, | 505 AppendCluster(source_id, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 | 577 |
584 if (track_number == kTextTrackNum || | 578 if (track_number == kTextTrackNum || |
585 track_number == kAlternateTextTrackNum) { | 579 track_number == kAlternateTextTrackNum) { |
586 block_info.duration = kTextBlockDuration; | 580 block_info.duration = kTextBlockDuration; |
587 ASSERT_EQ(kWebMFlagKeyframe, block_info.flags) | 581 ASSERT_EQ(kWebMFlagKeyframe, block_info.flags) |
588 << "Text block with timestamp " << block_info.timestamp_in_ms | 582 << "Text block with timestamp " << block_info.timestamp_in_ms |
589 << " was not marked as a key frame." | 583 << " was not marked as a key frame." |
590 << " All text blocks must be key frames"; | 584 << " All text blocks must be key frames"; |
591 } | 585 } |
592 | 586 |
593 if (track_number == kAudioTrackNum) | 587 if (track_number == kAudioTrackNum || |
588 track_number == kAlternateAudioTrackNum) | |
594 ASSERT_TRUE(block_info.flags & kWebMFlagKeyframe); | 589 ASSERT_TRUE(block_info.flags & kWebMFlagKeyframe); |
595 | 590 |
596 blocks->push_back(block_info); | 591 blocks->push_back(block_info); |
597 } | 592 } |
598 } | 593 } |
599 | 594 |
600 scoped_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, | 595 scoped_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, |
601 bool unknown_size) { | 596 bool unknown_size) { |
602 DCHECK_GT(blocks.size(), 0u); | 597 DCHECK_GT(blocks.size(), 0u); |
603 ClusterBuilder cb; | 598 ClusterBuilder cb; |
604 | 599 |
605 std::vector<uint8_t> data(10); | 600 std::vector<uint8_t> data(10); |
606 for (size_t i = 0; i < blocks.size(); ++i) { | 601 for (size_t i = 0; i < blocks.size(); ++i) { |
607 if (i == 0) | 602 if (i == 0) |
608 cb.SetClusterTimecode(blocks[i].timestamp_in_ms); | 603 cb.SetClusterTimecode(blocks[i].timestamp_in_ms); |
609 | 604 |
610 if (blocks[i].duration) { | 605 if (blocks[i].duration) { |
611 if (blocks[i].track_number == kVideoTrackNum) { | 606 if (blocks[i].track_number == kVideoTrackNum || |
607 blocks[i].track_number == kAlternateVideoTrackNum) { | |
612 AddVideoBlockGroup(&cb, | 608 AddVideoBlockGroup(&cb, |
613 blocks[i].track_number, blocks[i].timestamp_in_ms, | 609 blocks[i].track_number, blocks[i].timestamp_in_ms, |
614 blocks[i].duration, blocks[i].flags); | 610 blocks[i].duration, blocks[i].flags); |
615 } else { | 611 } else { |
616 cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, | 612 cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, |
617 blocks[i].duration, blocks[i].flags, | 613 blocks[i].duration, blocks[i].flags, |
618 &data[0], data.size()); | 614 &data[0], data.size()); |
619 } | 615 } |
620 } else { | 616 } else { |
621 cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, | 617 cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
791 | 787 |
792 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { | 788 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { |
793 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 789 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, |
794 base::Unretained(this), | 790 base::Unretained(this), |
795 expected_status); | 791 expected_status); |
796 } | 792 } |
797 | 793 |
798 enum StreamFlags { | 794 enum StreamFlags { |
799 HAS_AUDIO = 1 << 0, | 795 HAS_AUDIO = 1 << 0, |
800 HAS_VIDEO = 1 << 1, | 796 HAS_VIDEO = 1 << 1, |
801 HAS_TEXT = 1 << 2 | 797 HAS_TEXT = 1 << 2, |
798 USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3, | |
799 USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4, | |
800 USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5, | |
802 }; | 801 }; |
803 | 802 |
804 bool InitDemuxer(int stream_flags) { | 803 bool InitDemuxer(int stream_flags) { |
805 return InitDemuxerWithEncryptionInfo(stream_flags, false, false); | 804 return InitDemuxerWithEncryptionInfo(stream_flags, false, false); |
806 } | 805 } |
807 | 806 |
808 void ExpectInitMediaLogs(int stream_flags) { | 807 void ExpectInitMediaLogs(int stream_flags) { |
809 if (stream_flags & HAS_AUDIO) { | 808 if (stream_flags & HAS_AUDIO) { |
810 EXPECT_MEDIA_LOG(FoundStream("audio")); | 809 EXPECT_MEDIA_LOG(FoundStream("audio")); |
811 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis")); | 810 EXPECT_MEDIA_LOG(CodecName("audio", "vorbis")); |
(...skipping 30 matching lines...) Expand all Loading... | |
842 arraysize(kEncryptedMediaInitData)))) | 841 arraysize(kEncryptedMediaInitData)))) |
843 .Times(Exactly(need_key_count)); | 842 .Times(Exactly(need_key_count)); |
844 } | 843 } |
845 | 844 |
846 // Adding expectations prior to CreateInitDoneCB() here because InSequence | 845 // Adding expectations prior to CreateInitDoneCB() here because InSequence |
847 // tests require init segment received before duration set. Also, only | 846 // tests require init segment received before duration set. Also, only |
848 // expect an init segment received callback if there is actually a track in | 847 // expect an init segment received callback if there is actually a track in |
849 // it. | 848 // it. |
850 if (stream_flags != 0) { | 849 if (stream_flags != 0) { |
851 ExpectInitMediaLogs(stream_flags); | 850 ExpectInitMediaLogs(stream_flags); |
852 EXPECT_CALL(*this, InitSegmentReceived(_)); | 851 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
853 } else { | 852 } else { |
854 // OnNewConfigs() requires at least one audio, video, or text track. | 853 // OnNewConfigs() requires at least one audio, video, or text track. |
855 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 854 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
856 } | 855 } |
857 | 856 |
858 demuxer_->Initialize( | 857 demuxer_->Initialize( |
859 &host_, CreateInitDoneCB(expected_duration, expected_status), true); | 858 &host_, CreateInitDoneCB(expected_duration, expected_status), true); |
860 | 859 |
861 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) | 860 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) |
862 return false; | 861 return false; |
(...skipping 21 matching lines...) Expand all Loading... | |
884 | 883 |
885 if (has_text) { | 884 if (has_text) { |
886 audio_flags |= HAS_TEXT; | 885 audio_flags |= HAS_TEXT; |
887 video_flags |= HAS_TEXT; | 886 video_flags |= HAS_TEXT; |
888 } | 887 } |
889 | 888 |
890 // Note: Unlike InitDemuxerWithEncryptionInfo, this method is currently | 889 // Note: Unlike InitDemuxerWithEncryptionInfo, this method is currently |
891 // incompatible with InSequence tests. Refactoring of the duration | 890 // incompatible with InSequence tests. Refactoring of the duration |
892 // set expectation to not be added during CreateInitDoneCB() could fix this. | 891 // set expectation to not be added during CreateInitDoneCB() could fix this. |
893 ExpectInitMediaLogs(audio_flags); | 892 ExpectInitMediaLogs(audio_flags); |
894 EXPECT_CALL(*this, InitSegmentReceived(_)); | 893 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
895 AppendInitSegmentWithSourceId(audio_id, audio_flags); | 894 AppendInitSegmentWithSourceId(audio_id, audio_flags); |
896 | 895 |
897 ExpectInitMediaLogs(video_flags); | 896 ExpectInitMediaLogs(video_flags); |
898 EXPECT_CALL(*this, InitSegmentReceived(_)); | 897 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
899 AppendInitSegmentWithSourceId(video_id, video_flags); | 898 AppendInitSegmentWithSourceId(video_id, video_flags); |
900 return true; | 899 return true; |
901 } | 900 } |
902 | 901 |
903 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, | 902 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, |
904 const std::string& video_id) { | 903 const std::string& video_id) { |
905 return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false); | 904 return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false); |
906 } | 905 } |
907 | 906 |
908 // Initializes the demuxer with data from 2 files with different | 907 // Initializes the demuxer with data from 2 files with different |
(...skipping 15 matching lines...) Expand all Loading... | |
924 // bear-640x360.webm : [527-759) | 923 // bear-640x360.webm : [527-759) |
925 bool InitDemuxerWithConfigChangeData() { | 924 bool InitDemuxerWithConfigChangeData() { |
926 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); | 925 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); |
927 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); | 926 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); |
928 | 927 |
929 EXPECT_CALL(*this, DemuxerOpened()); | 928 EXPECT_CALL(*this, DemuxerOpened()); |
930 | 929 |
931 // Adding expectation prior to CreateInitDoneCB() here because InSequence | 930 // Adding expectation prior to CreateInitDoneCB() here because InSequence |
932 // tests require init segment received before duration set. | 931 // tests require init segment received before duration set. |
933 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); | 932 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); |
934 EXPECT_CALL(*this, InitSegmentReceived(_)); | 933 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
935 demuxer_->Initialize( | 934 demuxer_->Initialize( |
936 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), | 935 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), |
937 PIPELINE_OK), true); | 936 PIPELINE_OK), true); |
938 | 937 |
939 if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk) | 938 if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk) |
940 return false; | 939 return false; |
941 | 940 |
942 // Append the whole bear1 file. | 941 // Append the whole bear1 file. |
943 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)).Times(7); | 942 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)).Times(7); |
944 // Expect duration adjustment since actual duration differs slightly from | 943 // Expect duration adjustment since actual duration differs slightly from |
945 // duration in the init segment. | 944 // duration in the init segment. |
946 EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2746))); | 945 EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2746))); |
947 AppendData(bear1->data(), bear1->data_size()); | 946 AppendData(bear1->data(), bear1->data_size()); |
948 // Last audio frame has timestamp 2721 and duration 24 (estimated from max | 947 // Last audio frame has timestamp 2721 and duration 24 (estimated from max |
949 // seen so far for audio track). | 948 // seen so far for audio track). |
950 // Last video frame has timestamp 2703 and duration 33 (from TrackEntry | 949 // Last video frame has timestamp 2703 and duration 33 (from TrackEntry |
951 // DefaultDuration for video track). | 950 // DefaultDuration for video track). |
952 CheckExpectedRanges("{ [0,2736) }"); | 951 CheckExpectedRanges("{ [0,2736) }"); |
953 | 952 |
954 // Append initialization segment for bear2. | 953 // Append initialization segment for bear2. |
955 // Note: Offsets here and below are derived from | 954 // Note: Offsets here and below are derived from |
956 // media/test/data/bear-640x360-manifest.js and | 955 // media/test/data/bear-640x360-manifest.js and |
957 // media/test/data/bear-320x240-manifest.js which were | 956 // media/test/data/bear-320x240-manifest.js which were |
958 // generated from media/test/data/bear-640x360.webm and | 957 // generated from media/test/data/bear-640x360.webm and |
959 // media/test/data/bear-320x240.webm respectively. | 958 // media/test/data/bear-320x240.webm respectively. |
960 EXPECT_CALL(*this, InitSegmentReceived(_)); | 959 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
961 AppendData(bear2->data(), 4340); | 960 AppendData(bear2->data(), 4340); |
962 | 961 |
963 // Append a media segment that goes from [0.527000, 1.014000). | 962 // Append a media segment that goes from [0.527000, 1.014000). |
964 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); | 963 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); |
965 EXPECT_MEDIA_LOG(GeneratedSplice(20000, 527000)); | 964 EXPECT_MEDIA_LOG(GeneratedSplice(20000, 527000)); |
966 AppendData(bear2->data() + 55290, 18785); | 965 AppendData(bear2->data() + 55290, 18785); |
967 CheckExpectedRanges("{ [0,1027) [1201,2736) }"); | 966 CheckExpectedRanges("{ [0,1027) [1201,2736) }"); |
968 | 967 |
969 // Append initialization segment for bear1 & fill gap with [779-1197) | 968 // Append initialization segment for bear1 & fill gap with [779-1197) |
970 // segment. | 969 // segment. |
971 EXPECT_CALL(*this, InitSegmentReceived(_)); | 970 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
972 AppendData(bear1->data(), 4370); | 971 AppendData(bear1->data(), 4370); |
973 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)); | 972 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)); |
974 EXPECT_MEDIA_LOG(GeneratedSplice(26000, 779000)); | 973 EXPECT_MEDIA_LOG(GeneratedSplice(26000, 779000)); |
975 AppendData(bear1->data() + 72737, 28183); | 974 AppendData(bear1->data() + 72737, 28183); |
976 CheckExpectedRanges("{ [0,2736) }"); | 975 CheckExpectedRanges("{ [0,2736) }"); |
977 | 976 |
978 MarkEndOfStream(PIPELINE_OK); | 977 MarkEndOfStream(PIPELINE_OK); |
979 return true; | 978 return true; |
980 } | 979 } |
981 | 980 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1309 int stream_flags) { | 1308 int stream_flags) { |
1310 EXPECT_CALL(*this, DemuxerOpened()); | 1309 EXPECT_CALL(*this, DemuxerOpened()); |
1311 demuxer_->Initialize( | 1310 demuxer_->Initialize( |
1312 &host_, CreateInitDoneCB(duration, PIPELINE_OK), true); | 1311 &host_, CreateInitDoneCB(duration, PIPELINE_OK), true); |
1313 | 1312 |
1314 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) | 1313 if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk) |
1315 return false; | 1314 return false; |
1316 | 1315 |
1317 // Read a WebM file into memory and send the data to the demuxer. | 1316 // Read a WebM file into memory and send the data to the demuxer. |
1318 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 1317 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
1319 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1318 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
1320 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); | 1319 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); |
1321 | 1320 |
1322 // Verify that the timestamps on the first few packets match what we | 1321 // Verify that the timestamps on the first few packets match what we |
1323 // expect. | 1322 // expect. |
1324 for (size_t i = 0; | 1323 for (size_t i = 0; |
1325 (timestamps[i].audio_time_ms != kSkip || | 1324 (timestamps[i].audio_time_ms != kSkip || |
1326 timestamps[i].video_time_ms != kSkip); | 1325 timestamps[i].video_time_ms != kSkip); |
1327 i++) { | 1326 i++) { |
1328 bool audio_read_done = false; | 1327 bool audio_read_done = false; |
1329 bool video_read_done = false; | 1328 bool video_read_done = false; |
(...skipping 16 matching lines...) Expand all Loading... | |
1346 } | 1345 } |
1347 | 1346 |
1348 return true; | 1347 return true; |
1349 } | 1348 } |
1350 | 1349 |
1351 MOCK_METHOD0(DemuxerOpened, void()); | 1350 MOCK_METHOD0(DemuxerOpened, void()); |
1352 MOCK_METHOD2(OnEncryptedMediaInitData, | 1351 MOCK_METHOD2(OnEncryptedMediaInitData, |
1353 void(EmeInitDataType init_data_type, | 1352 void(EmeInitDataType init_data_type, |
1354 const std::vector<uint8_t>& init_data)); | 1353 const std::vector<uint8_t>& init_data)); |
1355 | 1354 |
1356 MOCK_METHOD1(InitSegmentReceived, void(scoped_ptr<MediaTracks>&)); | 1355 MOCK_METHOD1(InitSegmentReceivedMock, void(scoped_ptr<MediaTracks>&)); |
1357 | 1356 |
1358 void Seek(base::TimeDelta seek_time) { | 1357 void Seek(base::TimeDelta seek_time) { |
1359 demuxer_->StartWaitingForSeek(seek_time); | 1358 demuxer_->StartWaitingForSeek(seek_time); |
1360 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); | 1359 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); |
1361 message_loop_.RunUntilIdle(); | 1360 message_loop_.RunUntilIdle(); |
1362 } | 1361 } |
1363 | 1362 |
1364 void MarkEndOfStream(PipelineStatus status) { | 1363 void MarkEndOfStream(PipelineStatus status) { |
1365 demuxer_->MarkEndOfStream(status); | 1364 demuxer_->MarkEndOfStream(status); |
1366 message_loop_.RunUntilIdle(); | 1365 message_loop_.RunUntilIdle(); |
(...skipping 17 matching lines...) Expand all Loading... | |
1384 Demuxer::MediaTracksUpdatedCB init_segment_received_cb_; | 1383 Demuxer::MediaTracksUpdatedCB init_segment_received_cb_; |
1385 | 1384 |
1386 base::TimeDelta append_window_start_for_next_append_; | 1385 base::TimeDelta append_window_start_for_next_append_; |
1387 base::TimeDelta append_window_end_for_next_append_; | 1386 base::TimeDelta append_window_end_for_next_append_; |
1388 | 1387 |
1389 // Map of source id to timestamp offset to use for the next AppendData() | 1388 // Map of source id to timestamp offset to use for the next AppendData() |
1390 // operation for that source id. | 1389 // operation for that source id. |
1391 std::map<std::string, base::TimeDelta> timestamp_offset_map_; | 1390 std::map<std::string, base::TimeDelta> timestamp_offset_map_; |
1392 | 1391 |
1393 public: | 1392 public: |
1394 // A workaround for gtest mocks not allowing moving scoped_ptrs. | 1393 void InitSegmentReceived(scoped_ptr<MediaTracks> tracks) { |
1395 void InitSegmentReceivedWrapper(scoped_ptr<MediaTracks> tracks) { | 1394 DCHECK(tracks.get()); |
1396 InitSegmentReceived(tracks); | 1395 DCHECK_GT(tracks->tracks().size(), 0u); |
1396 | |
1397 InitSegmentReceivedMock(tracks); | |
1397 } | 1398 } |
1398 | 1399 |
1399 private: | 1400 private: |
1400 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 1401 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
1401 }; | 1402 }; |
1402 | 1403 |
1403 TEST_F(ChunkDemuxerTest, Init) { | 1404 TEST_F(ChunkDemuxerTest, Init) { |
1404 InSequence s; | 1405 InSequence s; |
1405 | 1406 |
1406 // Test no streams, audio-only, video-only, and audio & video scenarios. | 1407 // Test no streams, audio-only, video-only, and audio & video scenarios. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1551 ASSERT_TRUE(video_stream); | 1552 ASSERT_TRUE(video_stream); |
1552 ASSERT_TRUE(text_stream); | 1553 ASSERT_TRUE(text_stream); |
1553 | 1554 |
1554 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23), | 1555 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23), |
1555 MuxedStreamInfo(kVideoTrackNum, "0K 30", 30), | 1556 MuxedStreamInfo(kVideoTrackNum, "0K 30", 30), |
1556 MuxedStreamInfo(kTextTrackNum, "10K")); | 1557 MuxedStreamInfo(kTextTrackNum, "10K")); |
1557 CheckExpectedRanges("{ [0,46) }"); | 1558 CheckExpectedRanges("{ [0,46) }"); |
1558 | 1559 |
1559 scoped_ptr<uint8_t[]> info_tracks; | 1560 scoped_ptr<uint8_t[]> info_tracks; |
1560 int info_tracks_size = 0; | 1561 int info_tracks_size = 0; |
1561 CreateInitSegmentWithAlternateTextTrackNum(HAS_TEXT | HAS_AUDIO | HAS_VIDEO, | 1562 CreateInitSegment( |
1562 false, false, | 1563 HAS_TEXT | HAS_AUDIO | HAS_VIDEO | USE_ALTERNATE_TEXT_TRACK_ID, false, |
1563 &info_tracks, &info_tracks_size); | 1564 false, &info_tracks, &info_tracks_size); |
1564 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1565 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
1565 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, | 1566 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, |
1566 append_window_start_for_next_append_, | 1567 append_window_start_for_next_append_, |
1567 append_window_end_for_next_append_, | 1568 append_window_end_for_next_append_, |
1568 ×tamp_offset_map_[kSourceId]); | 1569 ×tamp_offset_map_[kSourceId]); |
1569 | 1570 |
1570 AppendMuxedCluster( | 1571 AppendMuxedCluster( |
1571 MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), | 1572 MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), |
1572 MuxedStreamInfo(kVideoTrackNum, "60K", | 1573 MuxedStreamInfo(kVideoTrackNum, "60K", |
1573 WebMClusterParser::kDefaultVideoBufferDurationInMs), | 1574 WebMClusterParser::kDefaultVideoBufferDurationInMs), |
1574 MuxedStreamInfo(kAlternateTextTrackNum, "45K")); | 1575 MuxedStreamInfo(kAlternateTextTrackNum, "45K")); |
1575 | 1576 |
1576 CheckExpectedRanges("{ [0,92) }"); | 1577 CheckExpectedRanges("{ [0,92) }"); |
1577 CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K"); | 1578 CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K"); |
1578 CheckExpectedBuffers(video_stream, "0K 30 60K"); | 1579 CheckExpectedBuffers(video_stream, "0K 30 60K"); |
1579 CheckExpectedBuffers(text_stream, "10K 45K"); | 1580 CheckExpectedBuffers(text_stream, "10K 45K"); |
1580 | 1581 |
1581 ShutdownDemuxer(); | 1582 ShutdownDemuxer(); |
1582 } | 1583 } |
1583 | 1584 |
1585 TEST_F(ChunkDemuxerTest, AudioVideoTrackIdsChange) { | |
1586 // Test with 1 audio and 1 video stream. Send a second init segment in which | |
1587 // the audio and video track IDs change. Verify that appended buffers before | |
1588 // and after the second init segment map to the same underlying track buffers. | |
1589 CreateNewDemuxer(); | |
1590 ASSERT_TRUE( | |
1591 InitDemuxerWithEncryptionInfo(HAS_AUDIO | HAS_VIDEO, false, false)); | |
1592 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
1593 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | |
1594 ASSERT_TRUE(audio_stream); | |
1595 ASSERT_TRUE(video_stream); | |
1596 | |
1597 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23), | |
1598 MuxedStreamInfo(kVideoTrackNum, "0K 30", 30)); | |
1599 CheckExpectedRanges("{ [0,46) }"); | |
1600 | |
1601 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); | |
1602 AppendInitSegment(HAS_AUDIO | HAS_VIDEO | USE_ALTERNATE_AUDIO_TRACK_ID | | |
1603 USE_ALTERNATE_VIDEO_TRACK_ID); | |
1604 AppendMuxedCluster(MuxedStreamInfo(kAlternateAudioTrackNum, "46K 69K", 63), | |
1605 MuxedStreamInfo(kAlternateVideoTrackNum, "60K", 23)); | |
1606 CheckExpectedRanges("{ [0,92) }"); | |
1607 CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K"); | |
1608 CheckExpectedBuffers(video_stream, "0K 30 60K"); | |
1609 | |
1610 ShutdownDemuxer(); | |
1611 } | |
1612 | |
1584 TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) { | 1613 TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) { |
1585 // Tests that non-key-frames following an init segment are allowed | 1614 // Tests that non-key-frames following an init segment are allowed |
1586 // and dropped, as expected if the initialization segment received | 1615 // and dropped, as expected if the initialization segment received |
1587 // algorithm correctly sets the needs random access point flag to true for all | 1616 // algorithm correctly sets the needs random access point flag to true for all |
1588 // track buffers. Note that the first initialization segment is insufficient | 1617 // track buffers. Note that the first initialization segment is insufficient |
1589 // to fully test this since needs random access point flag initializes to | 1618 // to fully test this since needs random access point flag initializes to |
1590 // true. | 1619 // true. |
1591 CreateNewDemuxer(); | 1620 CreateNewDemuxer(); |
1592 DemuxerStream* text_stream = NULL; | 1621 DemuxerStream* text_stream = NULL; |
1593 EXPECT_CALL(host_, AddTextStream(_, _)) | 1622 EXPECT_CALL(host_, AddTextStream(_, _)) |
1594 .WillOnce(SaveArg<0>(&text_stream)); | 1623 .WillOnce(SaveArg<0>(&text_stream)); |
1595 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | 1624 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
1596 HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false)); | 1625 HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false)); |
1597 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 1626 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
1598 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 1627 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
1599 ASSERT_TRUE(audio_stream && video_stream && text_stream); | 1628 ASSERT_TRUE(audio_stream && video_stream && text_stream); |
1600 | 1629 |
1601 AppendMuxedCluster( | 1630 AppendMuxedCluster( |
1602 MuxedStreamInfo(kAudioTrackNum, "23K", | 1631 MuxedStreamInfo(kAudioTrackNum, "23K", |
1603 WebMClusterParser::kDefaultAudioBufferDurationInMs), | 1632 WebMClusterParser::kDefaultAudioBufferDurationInMs), |
1604 MuxedStreamInfo(kVideoTrackNum, "0 30K", 30), | 1633 MuxedStreamInfo(kVideoTrackNum, "0 30K", 30), |
1605 MuxedStreamInfo(kTextTrackNum, "25K 40K")); | 1634 MuxedStreamInfo(kTextTrackNum, "25K 40K")); |
1606 CheckExpectedRanges("{ [23,46) }"); | 1635 CheckExpectedRanges("{ [23,46) }"); |
1607 | 1636 |
1608 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1637 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
1609 AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO); | 1638 AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO); |
1610 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), | 1639 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), |
1611 MuxedStreamInfo(kVideoTrackNum, "60 90K", 30), | 1640 MuxedStreamInfo(kVideoTrackNum, "60 90K", 30), |
1612 MuxedStreamInfo(kTextTrackNum, "80K 90K")); | 1641 MuxedStreamInfo(kTextTrackNum, "80K 90K")); |
1613 CheckExpectedRanges("{ [23,92) }"); | 1642 CheckExpectedRanges("{ [23,92) }"); |
1614 | 1643 |
1615 CheckExpectedBuffers(audio_stream, "23K 46K 69K"); | 1644 CheckExpectedBuffers(audio_stream, "23K 46K 69K"); |
1616 CheckExpectedBuffers(video_stream, "30K 90K"); | 1645 CheckExpectedBuffers(video_stream, "30K 90K"); |
1617 CheckExpectedBuffers(text_stream, "25K 40K 80K 90K"); | 1646 CheckExpectedBuffers(text_stream, "25K 40K 80K 90K"); |
1618 } | 1647 } |
1619 | 1648 |
1620 // Make sure that the demuxer reports an error if Shutdown() | 1649 // Make sure that the demuxer reports an error if Shutdown() |
1621 // is called before all the initialization segments are appended. | 1650 // is called before all the initialization segments are appended. |
1622 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { | 1651 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { |
1623 EXPECT_CALL(*this, DemuxerOpened()); | 1652 EXPECT_CALL(*this, DemuxerOpened()); |
1624 demuxer_->Initialize( | 1653 demuxer_->Initialize( |
1625 &host_, CreateInitDoneCB( | 1654 &host_, CreateInitDoneCB( |
1626 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1655 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1627 | 1656 |
1628 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); | 1657 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
1629 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); | 1658 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); |
1630 | 1659 |
1631 ExpectInitMediaLogs(HAS_AUDIO); | 1660 ExpectInitMediaLogs(HAS_AUDIO); |
1632 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1661 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
1633 AppendInitSegmentWithSourceId("audio", HAS_AUDIO); | 1662 AppendInitSegmentWithSourceId("audio", HAS_AUDIO); |
1634 | 1663 |
1635 ShutdownDemuxer(); | 1664 ShutdownDemuxer(); |
1636 } | 1665 } |
1637 | 1666 |
1638 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) { | 1667 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) { |
1639 EXPECT_CALL(*this, DemuxerOpened()); | 1668 EXPECT_CALL(*this, DemuxerOpened()); |
1640 demuxer_->Initialize( | 1669 demuxer_->Initialize( |
1641 &host_, CreateInitDoneCB( | 1670 &host_, CreateInitDoneCB( |
1642 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1671 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1643 | 1672 |
1644 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); | 1673 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
1645 EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk); | 1674 EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk); |
1646 | 1675 |
1647 EXPECT_CALL(host_, AddTextStream(_, _)) | 1676 EXPECT_CALL(host_, AddTextStream(_, _)) |
1648 .Times(Exactly(1)); | 1677 .Times(Exactly(1)); |
1649 | 1678 |
1650 ExpectInitMediaLogs(HAS_VIDEO); | 1679 ExpectInitMediaLogs(HAS_VIDEO); |
1651 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1680 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
1652 AppendInitSegmentWithSourceId("video_and_text", HAS_VIDEO | HAS_TEXT); | 1681 AppendInitSegmentWithSourceId("video_and_text", HAS_VIDEO | HAS_TEXT); |
1653 | 1682 |
1654 ShutdownDemuxer(); | 1683 ShutdownDemuxer(); |
1655 } | 1684 } |
1656 | 1685 |
1657 // Verifies that all streams waiting for data receive an end of stream | 1686 // Verifies that all streams waiting for data receive an end of stream |
1658 // buffer when Shutdown() is called. | 1687 // buffer when Shutdown() is called. |
1659 TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) { | 1688 TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) { |
1660 DemuxerStream* text_stream = NULL; | 1689 DemuxerStream* text_stream = NULL; |
1661 EXPECT_CALL(host_, AddTextStream(_, _)) | 1690 EXPECT_CALL(host_, AddTextStream(_, _)) |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2161 memcpy(dst, info_tracks.get(), info_tracks_size); | 2190 memcpy(dst, info_tracks.get(), info_tracks_size); |
2162 dst += info_tracks_size; | 2191 dst += info_tracks_size; |
2163 | 2192 |
2164 memcpy(dst, cluster_a->data(), cluster_a->size()); | 2193 memcpy(dst, cluster_a->data(), cluster_a->size()); |
2165 dst += cluster_a->size(); | 2194 dst += cluster_a->size(); |
2166 | 2195 |
2167 memcpy(dst, cluster_b->data(), cluster_b->size()); | 2196 memcpy(dst, cluster_b->data(), cluster_b->size()); |
2168 dst += cluster_b->size(); | 2197 dst += cluster_b->size(); |
2169 | 2198 |
2170 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); | 2199 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); |
2171 EXPECT_CALL(*this, InitSegmentReceived(_)); | 2200 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
2172 AppendDataInPieces(buffer.get(), buffer_size); | 2201 AppendDataInPieces(buffer.get(), buffer_size); |
2173 | 2202 |
2174 GenerateExpectedReads(0, 9); | 2203 GenerateExpectedReads(0, 9); |
2175 } | 2204 } |
2176 | 2205 |
2177 TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) { | 2206 TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) { |
2178 struct BufferTimestamps buffer_timestamps[] = { | 2207 struct BufferTimestamps buffer_timestamps[] = { |
2179 {0, 0}, | 2208 {0, 0}, |
2180 {33, 3}, | 2209 {33, 3}, |
2181 {67, 6}, | 2210 {67, 6}, |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2352 EXPECT_CALL(*this, DemuxerOpened()); | 2381 EXPECT_CALL(*this, DemuxerOpened()); |
2353 demuxer_->Initialize( | 2382 demuxer_->Initialize( |
2354 &host_, | 2383 &host_, |
2355 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), | 2384 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), |
2356 true); | 2385 true); |
2357 | 2386 |
2358 std::vector<std::string> codecs(1); | 2387 std::vector<std::string> codecs(1); |
2359 codecs[0] = "vorbis"; | 2388 codecs[0] = "vorbis"; |
2360 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 2389 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
2361 ChunkDemuxer::kOk); | 2390 ChunkDemuxer::kOk); |
2362 demuxer_->SetTracksWatcher( | 2391 demuxer_->SetTracksWatcher(kSourceId, |
2363 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 2392 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
2364 base::Unretained(this))); | 2393 base::Unretained(this))); |
2365 | 2394 |
2366 // Video track is unexpected per mimetype. | 2395 // Video track is unexpected per mimetype. |
2367 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", true)); | 2396 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", true)); |
2368 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2397 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2369 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); | 2398 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
2370 } | 2399 } |
2371 | 2400 |
2372 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { | 2401 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { |
2373 EXPECT_CALL(*this, DemuxerOpened()); | 2402 EXPECT_CALL(*this, DemuxerOpened()); |
2374 demuxer_->Initialize( | 2403 demuxer_->Initialize( |
2375 &host_, | 2404 &host_, |
2376 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), | 2405 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), |
2377 true); | 2406 true); |
2378 | 2407 |
2379 std::vector<std::string> codecs(1); | 2408 std::vector<std::string> codecs(1); |
2380 codecs[0] = "vp8"; | 2409 codecs[0] = "vp8"; |
2381 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2410 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2382 ChunkDemuxer::kOk); | 2411 ChunkDemuxer::kOk); |
2383 demuxer_->SetTracksWatcher( | 2412 demuxer_->SetTracksWatcher(kSourceId, |
2384 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 2413 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
2385 base::Unretained(this))); | 2414 base::Unretained(this))); |
2386 | 2415 |
2387 // Audio track is unexpected per mimetype. | 2416 // Audio track is unexpected per mimetype. |
2388 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", true)); | 2417 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", true)); |
2389 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2418 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2390 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); | 2419 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
2391 } | 2420 } |
2392 | 2421 |
2393 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) { | 2422 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) { |
2394 EXPECT_CALL(*this, DemuxerOpened()); | 2423 EXPECT_CALL(*this, DemuxerOpened()); |
2395 demuxer_->Initialize( | 2424 demuxer_->Initialize( |
2396 &host_, | 2425 &host_, |
2397 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), | 2426 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), |
2398 true); | 2427 true); |
2399 | 2428 |
2400 std::vector<std::string> codecs(2); | 2429 std::vector<std::string> codecs(2); |
2401 codecs[0] = "vorbis"; | 2430 codecs[0] = "vorbis"; |
2402 codecs[1] = "vp8"; | 2431 codecs[1] = "vp8"; |
2403 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2432 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2404 ChunkDemuxer::kOk); | 2433 ChunkDemuxer::kOk); |
2405 demuxer_->SetTracksWatcher( | 2434 demuxer_->SetTracksWatcher(kSourceId, |
2406 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 2435 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
2407 base::Unretained(this))); | 2436 base::Unretained(this))); |
2408 | 2437 |
2409 // Video track is also expected per mimetype. | 2438 // Video track is also expected per mimetype. |
2410 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", false)); | 2439 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", false)); |
2411 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2440 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2412 AppendInitSegment(HAS_AUDIO); | 2441 AppendInitSegment(HAS_AUDIO); |
2413 } | 2442 } |
2414 | 2443 |
2415 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) { | 2444 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) { |
2416 EXPECT_CALL(*this, DemuxerOpened()); | 2445 EXPECT_CALL(*this, DemuxerOpened()); |
2417 demuxer_->Initialize( | 2446 demuxer_->Initialize( |
2418 &host_, | 2447 &host_, |
2419 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), | 2448 CreateInitDoneCB(kNoTimestamp(), CHUNK_DEMUXER_ERROR_APPEND_FAILED), |
2420 true); | 2449 true); |
2421 | 2450 |
2422 std::vector<std::string> codecs(2); | 2451 std::vector<std::string> codecs(2); |
2423 codecs[0] = "vorbis"; | 2452 codecs[0] = "vorbis"; |
2424 codecs[1] = "vp8"; | 2453 codecs[1] = "vp8"; |
2425 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2454 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2426 ChunkDemuxer::kOk); | 2455 ChunkDemuxer::kOk); |
2427 demuxer_->SetTracksWatcher( | 2456 demuxer_->SetTracksWatcher(kSourceId, |
2428 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, | 2457 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, |
2429 base::Unretained(this))); | 2458 base::Unretained(this))); |
2430 | 2459 |
2431 // Audio track is also expected per mimetype. | 2460 // Audio track is also expected per mimetype. |
2432 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", false)); | 2461 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", false)); |
2433 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2462 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2434 AppendInitSegment(HAS_VIDEO); | 2463 AppendInitSegment(HAS_VIDEO); |
2435 } | 2464 } |
2436 | 2465 |
2437 TEST_F(ChunkDemuxerTest, MultipleHeaders) { | 2466 TEST_F(ChunkDemuxerTest, MultipleHeaders) { |
2438 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 2467 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
2439 | 2468 |
2440 AppendCluster(kDefaultFirstCluster()); | 2469 AppendCluster(kDefaultFirstCluster()); |
2441 | 2470 |
2442 // Append another identical initialization segment. | 2471 // Append another identical initialization segment. |
2443 EXPECT_CALL(*this, InitSegmentReceived(_)); | 2472 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
2444 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); | 2473 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
2445 | 2474 |
2446 AppendCluster(kDefaultSecondCluster()); | 2475 AppendCluster(kDefaultSecondCluster()); |
2447 | 2476 |
2448 GenerateExpectedReads(0, 9); | 2477 GenerateExpectedReads(0, 9); |
2449 } | 2478 } |
2450 | 2479 |
2451 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) { | 2480 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) { |
2452 std::string audio_id = "audio1"; | 2481 std::string audio_id = "audio1"; |
2453 std::string video_id = "video1"; | 2482 std::string video_id = "video1"; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2489 | 2518 |
2490 std::string audio_id = "audio1"; | 2519 std::string audio_id = "audio1"; |
2491 std::string video_id = "video1"; | 2520 std::string video_id = "video1"; |
2492 | 2521 |
2493 ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk); | 2522 ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk); |
2494 | 2523 |
2495 // Adding an id with audio/video should fail because we already added audio. | 2524 // Adding an id with audio/video should fail because we already added audio. |
2496 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 2525 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); |
2497 | 2526 |
2498 ExpectInitMediaLogs(HAS_AUDIO); | 2527 ExpectInitMediaLogs(HAS_AUDIO); |
2499 EXPECT_CALL(*this, InitSegmentReceived(_)); | 2528 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
2500 AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO); | 2529 AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO); |
2501 | 2530 |
2502 // Adding an id after append should fail. | 2531 // Adding an id after append should fail. |
2503 ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit); | 2532 ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit); |
2504 } | 2533 } |
2505 | 2534 |
2506 // Test that Read() calls after a RemoveId() return "end of stream" buffers. | 2535 // Test that Read() calls after a RemoveId() return "end of stream" buffers. |
2507 TEST_F(ChunkDemuxerTest, RemoveId) { | 2536 TEST_F(ChunkDemuxerTest, RemoveId) { |
2508 std::string audio_id = "audio1"; | 2537 std::string audio_id = "audio1"; |
2509 std::string video_id = "video1"; | 2538 std::string video_id = "video1"; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2733 } | 2762 } |
2734 | 2763 |
2735 // Test ranges in an audio-only stream. | 2764 // Test ranges in an audio-only stream. |
2736 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 2765 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
2737 EXPECT_CALL(*this, DemuxerOpened()); | 2766 EXPECT_CALL(*this, DemuxerOpened()); |
2738 demuxer_->Initialize( | 2767 demuxer_->Initialize( |
2739 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 2768 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
2740 | 2769 |
2741 ASSERT_EQ(AddId(kSourceId, HAS_AUDIO), ChunkDemuxer::kOk); | 2770 ASSERT_EQ(AddId(kSourceId, HAS_AUDIO), ChunkDemuxer::kOk); |
2742 ExpectInitMediaLogs(HAS_AUDIO); | 2771 ExpectInitMediaLogs(HAS_AUDIO); |
2743 EXPECT_CALL(*this, InitSegmentReceived(_)); | 2772 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
2744 AppendInitSegment(HAS_AUDIO); | 2773 AppendInitSegment(HAS_AUDIO); |
2745 | 2774 |
2746 // Test a simple cluster. | 2775 // Test a simple cluster. |
2747 AppendCluster( | 2776 AppendCluster( |
2748 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 2777 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
2749 | 2778 |
2750 CheckExpectedRanges("{ [0,92) }"); | 2779 CheckExpectedRanges("{ [0,92) }"); |
2751 | 2780 |
2752 // Append a disjoint cluster to check for two separate ranges. | 2781 // Append a disjoint cluster to check for two separate ranges. |
2753 AppendCluster(GenerateSingleStreamCluster( | 2782 AppendCluster(GenerateSingleStreamCluster( |
2754 150, 219, kAudioTrackNum, kAudioBlockDuration)); | 2783 150, 219, kAudioTrackNum, kAudioBlockDuration)); |
2755 | 2784 |
2756 CheckExpectedRanges("{ [0,92) [150,219) }"); | 2785 CheckExpectedRanges("{ [0,92) [150,219) }"); |
2757 } | 2786 } |
2758 | 2787 |
2759 // Test ranges in a video-only stream. | 2788 // Test ranges in a video-only stream. |
2760 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 2789 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
2761 EXPECT_CALL(*this, DemuxerOpened()); | 2790 EXPECT_CALL(*this, DemuxerOpened()); |
2762 demuxer_->Initialize( | 2791 demuxer_->Initialize( |
2763 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 2792 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
2764 | 2793 |
2765 ASSERT_EQ(AddId(kSourceId, HAS_VIDEO), ChunkDemuxer::kOk); | 2794 ASSERT_EQ(AddId(kSourceId, HAS_VIDEO), ChunkDemuxer::kOk); |
2766 ExpectInitMediaLogs(HAS_VIDEO); | 2795 ExpectInitMediaLogs(HAS_VIDEO); |
2767 EXPECT_CALL(*this, InitSegmentReceived(_)); | 2796 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
2768 AppendInitSegment(HAS_VIDEO); | 2797 AppendInitSegment(HAS_VIDEO); |
2769 | 2798 |
2770 // Test a simple cluster. | 2799 // Test a simple cluster. |
2771 AppendCluster( | 2800 AppendCluster( |
2772 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 2801 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
2773 | 2802 |
2774 CheckExpectedRanges("{ [0,132) }"); | 2803 CheckExpectedRanges("{ [0,132) }"); |
2775 | 2804 |
2776 // Append a disjoint cluster to check for two separate ranges. | 2805 // Append a disjoint cluster to check for two separate ranges. |
2777 AppendCluster(GenerateSingleStreamCluster( | 2806 AppendCluster(GenerateSingleStreamCluster( |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3432 // Audio: first PES: | 3461 // Audio: first PES: |
3433 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] | 3462 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] |
3434 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] | 3463 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] |
3435 // Video: last PES: | 3464 // Video: last PES: |
3436 // PTS: 370155 (0x0005a5eb) [= 90 kHz-Timestamp: 0:00:04.1128] | 3465 // PTS: 370155 (0x0005a5eb) [= 90 kHz-Timestamp: 0:00:04.1128] |
3437 // DTS: 367152 (0x00059a30) [= 90 kHz-Timestamp: 0:00:04.0794] | 3466 // DTS: 367152 (0x00059a30) [= 90 kHz-Timestamp: 0:00:04.0794] |
3438 // Audio: last PES: | 3467 // Audio: last PES: |
3439 // PTS: 353788 (0x000565fc) [= 90 kHz-Timestamp: 0:00:03.9309] | 3468 // PTS: 353788 (0x000565fc) [= 90 kHz-Timestamp: 0:00:03.9309] |
3440 | 3469 |
3441 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts"); | 3470 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts"); |
3442 EXPECT_CALL(*this, InitSegmentReceived(_)); | 3471 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
3443 AppendData(kSourceId, buffer->data(), buffer->data_size()); | 3472 AppendData(kSourceId, buffer->data(), buffer->data_size()); |
3444 | 3473 |
3445 // Confirm we're in the middle of parsing a media segment. | 3474 // Confirm we're in the middle of parsing a media segment. |
3446 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); | 3475 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); |
3447 | 3476 |
3448 // ResetParserState on the Mpeg2 TS parser triggers the emission of the last | 3477 // ResetParserState on the Mpeg2 TS parser triggers the emission of the last |
3449 // video buffer which is pending in the stream parser. | 3478 // video buffer which is pending in the stream parser. |
3450 Ranges<base::TimeDelta> range_before_abort = | 3479 Ranges<base::TimeDelta> range_before_abort = |
3451 demuxer_->GetBufferedRanges(kSourceId); | 3480 demuxer_->GetBufferedRanges(kSourceId); |
3452 demuxer_->ResetParserState(kSourceId, | 3481 demuxer_->ResetParserState(kSourceId, |
(...skipping 27 matching lines...) Expand all Loading... | |
3480 // Audio: first PES: | 3509 // Audio: first PES: |
3481 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] | 3510 // PTS: 126000 (0x0001ec30) [= 90 kHz-Timestamp: 0:00:01.4000] |
3482 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] | 3511 // DTS: 123910 (0x0001e406) [= 90 kHz-Timestamp: 0:00:01.3767] |
3483 // Video: last PES: | 3512 // Video: last PES: |
3484 // PTS: 370155 (0x0005a5eb) [= 90 kHz-Timestamp: 0:00:04.1128] | 3513 // PTS: 370155 (0x0005a5eb) [= 90 kHz-Timestamp: 0:00:04.1128] |
3485 // DTS: 367152 (0x00059a30) [= 90 kHz-Timestamp: 0:00:04.0794] | 3514 // DTS: 367152 (0x00059a30) [= 90 kHz-Timestamp: 0:00:04.0794] |
3486 // Audio: last PES: | 3515 // Audio: last PES: |
3487 // PTS: 353788 (0x000565fc) [= 90 kHz-Timestamp: 0:00:03.9309] | 3516 // PTS: 353788 (0x000565fc) [= 90 kHz-Timestamp: 0:00:03.9309] |
3488 | 3517 |
3489 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts"); | 3518 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts"); |
3490 EXPECT_CALL(*this, InitSegmentReceived(_)); | 3519 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
3491 AppendData(kSourceId, buffer->data(), buffer->data_size()); | 3520 AppendData(kSourceId, buffer->data(), buffer->data_size()); |
3492 | 3521 |
3493 // Confirm we're in the middle of parsing a media segment. | 3522 // Confirm we're in the middle of parsing a media segment. |
3494 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); | 3523 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); |
3495 | 3524 |
3496 // Seek to a time corresponding to buffers that will be emitted during the | 3525 // Seek to a time corresponding to buffers that will be emitted during the |
3497 // abort. | 3526 // abort. |
3498 Seek(base::TimeDelta::FromMilliseconds(4110)); | 3527 Seek(base::TimeDelta::FromMilliseconds(4110)); |
3499 | 3528 |
3500 // ResetParserState on the Mpeg2 TS parser triggers the emission of the last | 3529 // ResetParserState on the Mpeg2 TS parser triggers the emission of the last |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4091 // Set the append window to [50,150). | 4120 // Set the append window to [50,150). |
4092 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); | 4121 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); |
4093 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150); | 4122 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150); |
4094 | 4123 |
4095 // Read a WebM file into memory and send the data to the demuxer. The chunk | 4124 // Read a WebM file into memory and send the data to the demuxer. The chunk |
4096 // size has been chosen carefully to ensure the preroll buffer used by the | 4125 // size has been chosen carefully to ensure the preroll buffer used by the |
4097 // partial append window trim must come from a previous Append() call. | 4126 // partial append window trim must come from a previous Append() call. |
4098 scoped_refptr<DecoderBuffer> buffer = | 4127 scoped_refptr<DecoderBuffer> buffer = |
4099 ReadTestDataFile("bear-320x240-audio-only.webm"); | 4128 ReadTestDataFile("bear-320x240-audio-only.webm"); |
4100 ExpectInitMediaLogs(HAS_AUDIO); | 4129 ExpectInitMediaLogs(HAS_AUDIO); |
4101 EXPECT_CALL(*this, InitSegmentReceived(_)); | 4130 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
4102 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); | 4131 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); |
4103 AppendDataInPieces(buffer->data(), buffer->data_size(), 128); | 4132 AppendDataInPieces(buffer->data(), buffer->data_size(), 128); |
4104 | 4133 |
4105 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 4134 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
4106 CheckExpectedBuffers(stream, "50KP 50K 62K 86K 109K 122K 125K 128K"); | 4135 CheckExpectedBuffers(stream, "50KP 50K 62K 86K 109K 122K 125K 128K"); |
4107 } | 4136 } |
4108 | 4137 |
4109 TEST_F(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) { | 4138 TEST_F(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) { |
4110 EXPECT_CALL(*this, DemuxerOpened()); | 4139 EXPECT_CALL(*this, DemuxerOpened()); |
4111 demuxer_->Initialize( | 4140 demuxer_->Initialize( |
4112 &host_, | 4141 &host_, |
4113 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), | 4142 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), |
4114 true); | 4143 true); |
4115 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); | 4144 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); |
4116 | 4145 |
4117 // Set the append window such that the first file is completely before the | 4146 // Set the append window such that the first file is completely before the |
4118 // append window. | 4147 // append window. |
4119 // Expect duration adjustment since actual duration differs slightly from | 4148 // Expect duration adjustment since actual duration differs slightly from |
4120 // duration in the init segment. | 4149 // duration in the init segment. |
4121 const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746); | 4150 const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746); |
4122 append_window_start_for_next_append_ = duration_1; | 4151 append_window_start_for_next_append_ = duration_1; |
4123 | 4152 |
4124 // Read a WebM file into memory and append the data. | 4153 // Read a WebM file into memory and append the data. |
4125 scoped_refptr<DecoderBuffer> buffer = | 4154 scoped_refptr<DecoderBuffer> buffer = |
4126 ReadTestDataFile("bear-320x240-audio-only.webm"); | 4155 ReadTestDataFile("bear-320x240-audio-only.webm"); |
4127 ExpectInitMediaLogs(HAS_AUDIO); | 4156 ExpectInitMediaLogs(HAS_AUDIO); |
4128 EXPECT_CALL(*this, InitSegmentReceived(_)); | 4157 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
4129 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); | 4158 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); |
4130 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); | 4159 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); |
4131 CheckExpectedRanges("{ }"); | 4160 CheckExpectedRanges("{ }"); |
4132 | 4161 |
4133 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 4162 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
4134 AudioDecoderConfig config_1 = stream->audio_decoder_config(); | 4163 AudioDecoderConfig config_1 = stream->audio_decoder_config(); |
4135 | 4164 |
4136 // Read a second WebM with a different config in and append the data. | 4165 // Read a second WebM with a different config in and append the data. |
4137 scoped_refptr<DecoderBuffer> buffer2 = | 4166 scoped_refptr<DecoderBuffer> buffer2 = |
4138 ReadTestDataFile("bear-320x240-audio-only-48khz.webm"); | 4167 ReadTestDataFile("bear-320x240-audio-only-48khz.webm"); |
4139 EXPECT_CALL(*this, InitSegmentReceived(_)); | 4168 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
4140 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(21)); | 4169 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(21)); |
4141 EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber()); | 4170 EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber()); |
4142 ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1)); | 4171 ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1)); |
4143 AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512); | 4172 AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512); |
4144 CheckExpectedRanges("{ [2746,5519) }"); | 4173 CheckExpectedRanges("{ [2746,5519) }"); |
4145 | 4174 |
4146 Seek(duration_1); | 4175 Seek(duration_1); |
4147 ExpectConfigChanged(DemuxerStream::AUDIO); | 4176 ExpectConfigChanged(DemuxerStream::AUDIO); |
4148 ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config())); | 4177 ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config())); |
4149 CheckExpectedBuffers(stream, "2746K 2767K 2789K 2810K"); | 4178 CheckExpectedBuffers(stream, "2746K 2767K 2789K 2810K"); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4640 cluster->size() - video_start); | 4669 cluster->size() - video_start); |
4641 | 4670 |
4642 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); | 4671 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); |
4643 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); | 4672 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); |
4644 CheckExpectedRanges("{ [30,90) }"); | 4673 CheckExpectedRanges("{ [30,90) }"); |
4645 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); | 4674 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); |
4646 CheckExpectedBuffers(video_stream, "71K 81"); | 4675 CheckExpectedBuffers(video_stream, "71K 81"); |
4647 } | 4676 } |
4648 | 4677 |
4649 } // namespace media | 4678 } // namespace media |
OLD | NEW |