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