Chromium Code Reviews| 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> |
|
ddorwin
2016/04/21 22:54:54
Why isn't <memory> included in this file like the
| |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
| 17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 18 #include "media/base/audio_decoder_config.h" | 18 #include "media/base/audio_decoder_config.h" |
| 19 #include "media/base/decoder_buffer.h" | 19 #include "media/base/decoder_buffer.h" |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 | 243 |
| 244 class ChunkDemuxerTest : public ::testing::Test { | 244 class ChunkDemuxerTest : public ::testing::Test { |
| 245 protected: | 245 protected: |
| 246 enum CodecsIndex { | 246 enum CodecsIndex { |
| 247 AUDIO, | 247 AUDIO, |
| 248 VIDEO, | 248 VIDEO, |
| 249 MAX_CODECS_INDEX | 249 MAX_CODECS_INDEX |
| 250 }; | 250 }; |
| 251 | 251 |
| 252 // Default cluster to append first for simple tests. | 252 // Default cluster to append first for simple tests. |
| 253 scoped_ptr<Cluster> kDefaultFirstCluster() { | 253 std::unique_ptr<Cluster> kDefaultFirstCluster() { |
| 254 return GenerateCluster(0, 4); | 254 return GenerateCluster(0, 4); |
| 255 } | 255 } |
| 256 | 256 |
| 257 // Default cluster to append after kDefaultFirstCluster() | 257 // Default cluster to append after kDefaultFirstCluster() |
| 258 // has been appended. This cluster starts with blocks that | 258 // has been appended. This cluster starts with blocks that |
| 259 // have timestamps consistent with the end times of the blocks | 259 // have timestamps consistent with the end times of the blocks |
| 260 // in kDefaultFirstCluster() so that these two clusters represent | 260 // in kDefaultFirstCluster() so that these two clusters represent |
| 261 // a continuous region. | 261 // a continuous region. |
| 262 scoped_ptr<Cluster> kDefaultSecondCluster() { | 262 std::unique_ptr<Cluster> kDefaultSecondCluster() { |
| 263 return GenerateCluster(46, 66, 5); | 263 return GenerateCluster(46, 66, 5); |
| 264 } | 264 } |
| 265 | 265 |
| 266 ChunkDemuxerTest() | 266 ChunkDemuxerTest() |
| 267 : media_log_(new StrictMock<MockMediaLog>()), | 267 : media_log_(new StrictMock<MockMediaLog>()), |
| 268 append_window_end_for_next_append_(kInfiniteDuration()) { | 268 append_window_end_for_next_append_(kInfiniteDuration()) { |
| 269 init_segment_received_cb_ = base::Bind( | 269 init_segment_received_cb_ = base::Bind( |
| 270 &ChunkDemuxerTest::InitSegmentReceived, base::Unretained(this)); | 270 &ChunkDemuxerTest::InitSegmentReceived, base::Unretained(this)); |
| 271 CreateNewDemuxer(); | 271 CreateNewDemuxer(); |
| 272 } | 272 } |
| 273 | 273 |
| 274 void CreateNewDemuxer() { | 274 void CreateNewDemuxer() { |
| 275 base::Closure open_cb = | 275 base::Closure open_cb = |
| 276 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); | 276 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
| 277 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( | 277 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( |
| 278 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); | 278 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); |
| 279 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, | 279 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, |
| 280 media_log_, true)); | 280 media_log_, true)); |
| 281 } | 281 } |
| 282 | 282 |
| 283 virtual ~ChunkDemuxerTest() { | 283 virtual ~ChunkDemuxerTest() { |
| 284 ShutdownDemuxer(); | 284 ShutdownDemuxer(); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void CreateInitSegment(int stream_flags, | 287 void CreateInitSegment(int stream_flags, |
| 288 bool is_audio_encrypted, | 288 bool is_audio_encrypted, |
| 289 bool is_video_encrypted, | 289 bool is_video_encrypted, |
| 290 scoped_ptr<uint8_t[]>* buffer, | 290 std::unique_ptr<uint8_t[]>* buffer, |
| 291 int* size) { | 291 int* size) { |
| 292 bool has_audio = (stream_flags & HAS_AUDIO) != 0; | 292 bool has_audio = (stream_flags & HAS_AUDIO) != 0; |
| 293 bool has_video = (stream_flags & HAS_VIDEO) != 0; | 293 bool has_video = (stream_flags & HAS_VIDEO) != 0; |
| 294 bool has_text = (stream_flags & HAS_TEXT) != 0; | 294 bool has_text = (stream_flags & HAS_TEXT) != 0; |
| 295 scoped_refptr<DecoderBuffer> ebml_header; | 295 scoped_refptr<DecoderBuffer> ebml_header; |
| 296 scoped_refptr<DecoderBuffer> info; | 296 scoped_refptr<DecoderBuffer> info; |
| 297 scoped_refptr<DecoderBuffer> audio_track_entry; | 297 scoped_refptr<DecoderBuffer> audio_track_entry; |
| 298 scoped_refptr<DecoderBuffer> video_track_entry; | 298 scoped_refptr<DecoderBuffer> video_track_entry; |
| 299 scoped_refptr<DecoderBuffer> audio_content_encodings; | 299 scoped_refptr<DecoderBuffer> audio_content_encodings; |
| 300 scoped_refptr<DecoderBuffer> video_content_encodings; | 300 scoped_refptr<DecoderBuffer> video_content_encodings; |
| 301 scoped_refptr<DecoderBuffer> text_track_entry; | 301 scoped_refptr<DecoderBuffer> text_track_entry; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 base::Unretained(this))); | 470 base::Unretained(this))); |
| 471 return status; | 471 return status; |
| 472 } | 472 } |
| 473 #endif | 473 #endif |
| 474 | 474 |
| 475 void AppendData(const uint8_t* data, size_t length) { | 475 void AppendData(const uint8_t* data, size_t length) { |
| 476 AppendData(kSourceId, data, length); | 476 AppendData(kSourceId, data, length); |
| 477 } | 477 } |
| 478 | 478 |
| 479 void AppendCluster(const std::string& source_id, | 479 void AppendCluster(const std::string& source_id, |
| 480 scoped_ptr<Cluster> cluster) { | 480 std::unique_ptr<Cluster> cluster) { |
| 481 AppendData(source_id, cluster->data(), cluster->size()); | 481 AppendData(source_id, cluster->data(), cluster->size()); |
| 482 } | 482 } |
| 483 | 483 |
| 484 void AppendCluster(scoped_ptr<Cluster> cluster) { | 484 void AppendCluster(std::unique_ptr<Cluster> cluster) { |
| 485 AppendCluster(kSourceId, std::move(cluster)); | 485 AppendCluster(kSourceId, std::move(cluster)); |
| 486 } | 486 } |
| 487 | 487 |
| 488 void AppendCluster(int timecode, int block_count) { | 488 void AppendCluster(int timecode, int block_count) { |
| 489 AppendCluster(GenerateCluster(timecode, block_count)); | 489 AppendCluster(GenerateCluster(timecode, block_count)); |
| 490 } | 490 } |
| 491 | 491 |
| 492 void AppendSingleStreamCluster(const std::string& source_id, int track_number, | 492 void AppendSingleStreamCluster(const std::string& source_id, int track_number, |
| 493 int timecode, int block_count) { | 493 int timecode, int block_count) { |
| 494 int block_duration = 0; | 494 int block_duration = 0; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 } | 591 } |
| 592 | 592 |
| 593 if (track_number == kAudioTrackNum || | 593 if (track_number == kAudioTrackNum || |
| 594 track_number == kAlternateAudioTrackNum) | 594 track_number == kAlternateAudioTrackNum) |
| 595 ASSERT_TRUE(block_info.flags & kWebMFlagKeyframe); | 595 ASSERT_TRUE(block_info.flags & kWebMFlagKeyframe); |
| 596 | 596 |
| 597 blocks->push_back(block_info); | 597 blocks->push_back(block_info); |
| 598 } | 598 } |
| 599 } | 599 } |
| 600 | 600 |
| 601 scoped_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, | 601 std::unique_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, |
| 602 bool unknown_size) { | 602 bool unknown_size) { |
| 603 DCHECK_GT(blocks.size(), 0u); | 603 DCHECK_GT(blocks.size(), 0u); |
| 604 ClusterBuilder cb; | 604 ClusterBuilder cb; |
| 605 | 605 |
| 606 std::vector<uint8_t> data(10); | 606 std::vector<uint8_t> data(10); |
| 607 for (size_t i = 0; i < blocks.size(); ++i) { | 607 for (size_t i = 0; i < blocks.size(); ++i) { |
| 608 if (i == 0) | 608 if (i == 0) |
| 609 cb.SetClusterTimecode(blocks[i].timestamp_in_ms); | 609 cb.SetClusterTimecode(blocks[i].timestamp_in_ms); |
| 610 | 610 |
| 611 if (blocks[i].duration) { | 611 if (blocks[i].duration) { |
| 612 if (blocks[i].track_number == kVideoTrackNum || | 612 if (blocks[i].track_number == kVideoTrackNum || |
| 613 blocks[i].track_number == kAlternateVideoTrackNum) { | 613 blocks[i].track_number == kAlternateVideoTrackNum) { |
| 614 AddVideoBlockGroup(&cb, | 614 AddVideoBlockGroup(&cb, |
| 615 blocks[i].track_number, blocks[i].timestamp_in_ms, | 615 blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 616 blocks[i].duration, blocks[i].flags); | 616 blocks[i].duration, blocks[i].flags); |
| 617 } else { | 617 } else { |
| 618 cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, | 618 cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 619 blocks[i].duration, blocks[i].flags, | 619 blocks[i].duration, blocks[i].flags, |
| 620 &data[0], data.size()); | 620 &data[0], data.size()); |
| 621 } | 621 } |
| 622 } else { | 622 } else { |
| 623 cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, | 623 cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 624 blocks[i].flags, | 624 blocks[i].flags, |
| 625 &data[0], data.size()); | 625 &data[0], data.size()); |
| 626 } | 626 } |
| 627 } | 627 } |
| 628 | 628 |
| 629 return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); | 629 return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); |
| 630 } | 630 } |
| 631 | 631 |
| 632 scoped_ptr<Cluster> GenerateCluster( | 632 std::unique_ptr<Cluster> GenerateCluster( |
| 633 std::priority_queue<BlockInfo> block_queue, | 633 std::priority_queue<BlockInfo> block_queue, |
| 634 bool unknown_size) { | 634 bool unknown_size) { |
| 635 std::vector<BlockInfo> blocks(block_queue.size()); | 635 std::vector<BlockInfo> blocks(block_queue.size()); |
| 636 for (size_t i = block_queue.size() - 1; !block_queue.empty(); --i) { | 636 for (size_t i = block_queue.size() - 1; !block_queue.empty(); --i) { |
| 637 blocks[i] = block_queue.top(); | 637 blocks[i] = block_queue.top(); |
| 638 block_queue.pop(); | 638 block_queue.pop(); |
| 639 } | 639 } |
| 640 | 640 |
| 641 return GenerateCluster(blocks, unknown_size); | 641 return GenerateCluster(blocks, unknown_size); |
| 642 } | 642 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, | 691 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, |
| 692 const MuxedStreamInfo& msi_2, | 692 const MuxedStreamInfo& msi_2, |
| 693 const MuxedStreamInfo& msi_3) { | 693 const MuxedStreamInfo& msi_3) { |
| 694 std::vector<MuxedStreamInfo> msi(3); | 694 std::vector<MuxedStreamInfo> msi(3); |
| 695 msi[0] = msi_1; | 695 msi[0] = msi_1; |
| 696 msi[1] = msi_2; | 696 msi[1] = msi_2; |
| 697 msi[2] = msi_3; | 697 msi[2] = msi_3; |
| 698 AppendMuxedCluster(msi); | 698 AppendMuxedCluster(msi); |
| 699 } | 699 } |
| 700 | 700 |
| 701 scoped_ptr<Cluster> GenerateMuxedCluster( | 701 std::unique_ptr<Cluster> GenerateMuxedCluster( |
| 702 const std::vector<MuxedStreamInfo> msi) { | 702 const std::vector<MuxedStreamInfo> msi) { |
| 703 std::priority_queue<BlockInfo> block_queue; | 703 std::priority_queue<BlockInfo> block_queue; |
| 704 for (size_t i = 0; i < msi.size(); ++i) { | 704 for (size_t i = 0; i < msi.size(); ++i) { |
| 705 std::vector<BlockInfo> track_blocks; | 705 std::vector<BlockInfo> track_blocks; |
| 706 ParseBlockDescriptions(msi[i].track_number, msi[i].block_descriptions, | 706 ParseBlockDescriptions(msi[i].track_number, msi[i].block_descriptions, |
| 707 &track_blocks); | 707 &track_blocks); |
| 708 | 708 |
| 709 for (size_t j = 0; j < track_blocks.size(); ++j) { | 709 for (size_t j = 0; j < track_blocks.size(); ++j) { |
| 710 block_queue.push(track_blocks[j]); | 710 block_queue.push(track_blocks[j]); |
| 711 } | 711 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 | 755 |
| 756 void AppendInitSegmentWithSourceId(const std::string& source_id, | 756 void AppendInitSegmentWithSourceId(const std::string& source_id, |
| 757 int stream_flags) { | 757 int stream_flags) { |
| 758 AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false, false); | 758 AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false, false); |
| 759 } | 759 } |
| 760 | 760 |
| 761 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, | 761 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, |
| 762 int stream_flags, | 762 int stream_flags, |
| 763 bool is_audio_encrypted, | 763 bool is_audio_encrypted, |
| 764 bool is_video_encrypted) { | 764 bool is_video_encrypted) { |
| 765 scoped_ptr<uint8_t[]> info_tracks; | 765 std::unique_ptr<uint8_t[]> info_tracks; |
| 766 int info_tracks_size = 0; | 766 int info_tracks_size = 0; |
| 767 CreateInitSegment(stream_flags, | 767 CreateInitSegment(stream_flags, |
| 768 is_audio_encrypted, is_video_encrypted, | 768 is_audio_encrypted, is_video_encrypted, |
| 769 &info_tracks, &info_tracks_size); | 769 &info_tracks, &info_tracks_size); |
| 770 AppendData(source_id, info_tracks.get(), info_tracks_size); | 770 AppendData(source_id, info_tracks.get(), info_tracks_size); |
| 771 } | 771 } |
| 772 | 772 |
| 773 void AppendGarbage() { | 773 void AppendGarbage() { |
| 774 // Fill up an array with gibberish. | 774 // Fill up an array with gibberish. |
| 775 int garbage_cluster_size = 10; | 775 int garbage_cluster_size = 10; |
| 776 scoped_ptr<uint8_t[]> garbage_cluster(new uint8_t[garbage_cluster_size]); | 776 std::unique_ptr<uint8_t[]> garbage_cluster( |
| 777 new uint8_t[garbage_cluster_size]); | |
| 777 for (int i = 0; i < garbage_cluster_size; ++i) | 778 for (int i = 0; i < garbage_cluster_size; ++i) |
| 778 garbage_cluster[i] = i; | 779 garbage_cluster[i] = i; |
| 779 AppendData(garbage_cluster.get(), garbage_cluster_size); | 780 AppendData(garbage_cluster.get(), garbage_cluster_size); |
| 780 } | 781 } |
| 781 | 782 |
| 782 void InitDoneCalled(PipelineStatus expected_status, | 783 void InitDoneCalled(PipelineStatus expected_status, |
| 783 PipelineStatus status) { | 784 PipelineStatus status) { |
| 784 EXPECT_EQ(status, expected_status); | 785 EXPECT_EQ(status, expected_status); |
| 785 } | 786 } |
| 786 | 787 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 989 demuxer_->Shutdown(); | 990 demuxer_->Shutdown(); |
| 990 message_loop_.RunUntilIdle(); | 991 message_loop_.RunUntilIdle(); |
| 991 } | 992 } |
| 992 } | 993 } |
| 993 | 994 |
| 994 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64_t timecode) { | 995 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64_t timecode) { |
| 995 uint8_t data[] = {0x00}; | 996 uint8_t data[] = {0x00}; |
| 996 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); | 997 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); |
| 997 } | 998 } |
| 998 | 999 |
| 999 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { | 1000 std::unique_ptr<Cluster> GenerateCluster(int timecode, int block_count) { |
| 1000 return GenerateCluster(timecode, timecode, block_count); | 1001 return GenerateCluster(timecode, timecode, block_count); |
| 1001 } | 1002 } |
| 1002 | 1003 |
| 1003 void AddVideoBlockGroup(ClusterBuilder* cb, | 1004 void AddVideoBlockGroup(ClusterBuilder* cb, |
| 1004 int track_num, | 1005 int track_num, |
| 1005 int64_t timecode, | 1006 int64_t timecode, |
| 1006 int duration, | 1007 int duration, |
| 1007 int flags) { | 1008 int flags) { |
| 1008 const uint8_t* data = | 1009 const uint8_t* data = |
| 1009 (flags & kWebMFlagKeyframe) != 0 ? kVP8Keyframe : kVP8Interframe; | 1010 (flags & kWebMFlagKeyframe) != 0 ? kVP8Keyframe : kVP8Interframe; |
| 1010 int size = (flags & kWebMFlagKeyframe) != 0 ? sizeof(kVP8Keyframe) : | 1011 int size = (flags & kWebMFlagKeyframe) != 0 ? sizeof(kVP8Keyframe) : |
| 1011 sizeof(kVP8Interframe); | 1012 sizeof(kVP8Interframe); |
| 1012 cb->AddBlockGroup(track_num, timecode, duration, flags, data, size); | 1013 cb->AddBlockGroup(track_num, timecode, duration, flags, data, size); |
| 1013 } | 1014 } |
| 1014 | 1015 |
| 1015 scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode, | 1016 std::unique_ptr<Cluster> GenerateCluster(int first_audio_timecode, |
| 1016 int first_video_timecode, | 1017 int first_video_timecode, |
| 1017 int block_count) { | 1018 int block_count) { |
| 1018 return GenerateCluster(first_audio_timecode, first_video_timecode, | 1019 return GenerateCluster(first_audio_timecode, first_video_timecode, |
| 1019 block_count, false); | 1020 block_count, false); |
| 1020 } | 1021 } |
| 1021 scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode, | 1022 std::unique_ptr<Cluster> GenerateCluster(int first_audio_timecode, |
| 1022 int first_video_timecode, | 1023 int first_video_timecode, |
| 1023 int block_count, | 1024 int block_count, |
| 1024 bool unknown_size) { | 1025 bool unknown_size) { |
| 1025 CHECK_GT(block_count, 0); | 1026 CHECK_GT(block_count, 0); |
| 1026 | 1027 |
| 1027 std::priority_queue<BlockInfo> block_queue; | 1028 std::priority_queue<BlockInfo> block_queue; |
| 1028 | 1029 |
| 1029 if (block_count == 1) { | 1030 if (block_count == 1) { |
| 1030 block_queue.push(BlockInfo(kAudioTrackNum, | 1031 block_queue.push(BlockInfo(kAudioTrackNum, |
| 1031 first_audio_timecode, | 1032 first_audio_timecode, |
| 1032 kWebMFlagKeyframe, | 1033 kWebMFlagKeyframe, |
| 1033 kAudioBlockDuration)); | 1034 kAudioBlockDuration)); |
| 1034 return GenerateCluster(block_queue, unknown_size); | 1035 return GenerateCluster(block_queue, unknown_size); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1065 kWebMFlagKeyframe, | 1066 kWebMFlagKeyframe, |
| 1066 kAudioBlockDuration)); | 1067 kAudioBlockDuration)); |
| 1067 block_queue.push(BlockInfo(kVideoTrackNum, | 1068 block_queue.push(BlockInfo(kVideoTrackNum, |
| 1068 video_timecode, | 1069 video_timecode, |
| 1069 video_flag, | 1070 video_flag, |
| 1070 kVideoBlockDuration)); | 1071 kVideoBlockDuration)); |
| 1071 | 1072 |
| 1072 return GenerateCluster(block_queue, unknown_size); | 1073 return GenerateCluster(block_queue, unknown_size); |
| 1073 } | 1074 } |
| 1074 | 1075 |
| 1075 scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, | 1076 std::unique_ptr<Cluster> GenerateSingleStreamCluster(int timecode, |
| 1076 int end_timecode, | 1077 int end_timecode, |
| 1077 int track_number, | 1078 int track_number, |
| 1078 int block_duration) { | 1079 int block_duration) { |
| 1079 CHECK_GT(end_timecode, timecode); | 1080 CHECK_GT(end_timecode, timecode); |
| 1080 | 1081 |
| 1081 std::vector<uint8_t> data(kBlockSize); | 1082 std::vector<uint8_t> data(kBlockSize); |
| 1082 | 1083 |
| 1083 ClusterBuilder cb; | 1084 ClusterBuilder cb; |
| 1084 cb.SetClusterTimecode(timecode); | 1085 cb.SetClusterTimecode(timecode); |
| 1085 | 1086 |
| 1086 // Create simple blocks for everything except the last block. | 1087 // Create simple blocks for everything except the last block. |
| 1087 while (timecode < (end_timecode - block_duration)) { | 1088 while (timecode < (end_timecode - block_duration)) { |
| 1088 cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe, | 1089 cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1159 void GenerateAudioStreamExpectedReads(int timecode, int block_count) { | 1160 void GenerateAudioStreamExpectedReads(int timecode, int block_count) { |
| 1160 GenerateSingleStreamExpectedReads( | 1161 GenerateSingleStreamExpectedReads( |
| 1161 timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration); | 1162 timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration); |
| 1162 } | 1163 } |
| 1163 | 1164 |
| 1164 void GenerateVideoStreamExpectedReads(int timecode, int block_count) { | 1165 void GenerateVideoStreamExpectedReads(int timecode, int block_count) { |
| 1165 GenerateSingleStreamExpectedReads( | 1166 GenerateSingleStreamExpectedReads( |
| 1166 timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration); | 1167 timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration); |
| 1167 } | 1168 } |
| 1168 | 1169 |
| 1169 scoped_ptr<Cluster> GenerateEmptyCluster(int timecode) { | 1170 std::unique_ptr<Cluster> GenerateEmptyCluster(int timecode) { |
| 1170 ClusterBuilder cb; | 1171 ClusterBuilder cb; |
| 1171 cb.SetClusterTimecode(timecode); | 1172 cb.SetClusterTimecode(timecode); |
| 1172 return cb.Finish(); | 1173 return cb.Finish(); |
| 1173 } | 1174 } |
| 1174 | 1175 |
| 1175 void CheckExpectedRangesForMediaSource(const std::string& expected) { | 1176 void CheckExpectedRangesForMediaSource(const std::string& expected) { |
| 1176 CheckExpectedRanges(demuxer_->GetBufferedRanges(), expected); | 1177 CheckExpectedRanges(demuxer_->GetBufferedRanges(), expected); |
| 1177 } | 1178 } |
| 1178 | 1179 |
| 1179 void CheckExpectedRanges(const std::string& expected) { | 1180 void CheckExpectedRanges(const std::string& expected) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1351 } | 1352 } |
| 1352 | 1353 |
| 1353 return true; | 1354 return true; |
| 1354 } | 1355 } |
| 1355 | 1356 |
| 1356 MOCK_METHOD0(DemuxerOpened, void()); | 1357 MOCK_METHOD0(DemuxerOpened, void()); |
| 1357 MOCK_METHOD2(OnEncryptedMediaInitData, | 1358 MOCK_METHOD2(OnEncryptedMediaInitData, |
| 1358 void(EmeInitDataType init_data_type, | 1359 void(EmeInitDataType init_data_type, |
| 1359 const std::vector<uint8_t>& init_data)); | 1360 const std::vector<uint8_t>& init_data)); |
| 1360 | 1361 |
| 1361 MOCK_METHOD1(InitSegmentReceivedMock, void(scoped_ptr<MediaTracks>&)); | 1362 MOCK_METHOD1(InitSegmentReceivedMock, void(std::unique_ptr<MediaTracks>&)); |
| 1362 | 1363 |
| 1363 void Seek(base::TimeDelta seek_time) { | 1364 void Seek(base::TimeDelta seek_time) { |
| 1364 demuxer_->StartWaitingForSeek(seek_time); | 1365 demuxer_->StartWaitingForSeek(seek_time); |
| 1365 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); | 1366 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); |
| 1366 message_loop_.RunUntilIdle(); | 1367 message_loop_.RunUntilIdle(); |
| 1367 } | 1368 } |
| 1368 | 1369 |
| 1369 void MarkEndOfStream(PipelineStatus status) { | 1370 void MarkEndOfStream(PipelineStatus status) { |
| 1370 demuxer_->MarkEndOfStream(status); | 1371 demuxer_->MarkEndOfStream(status); |
| 1371 message_loop_.RunUntilIdle(); | 1372 message_loop_.RunUntilIdle(); |
| 1372 } | 1373 } |
| 1373 | 1374 |
| 1374 bool SetTimestampOffset(const std::string& id, | 1375 bool SetTimestampOffset(const std::string& id, |
| 1375 base::TimeDelta timestamp_offset) { | 1376 base::TimeDelta timestamp_offset) { |
| 1376 if (demuxer_->IsParsingMediaSegment(id)) | 1377 if (demuxer_->IsParsingMediaSegment(id)) |
| 1377 return false; | 1378 return false; |
| 1378 | 1379 |
| 1379 timestamp_offset_map_[id] = timestamp_offset; | 1380 timestamp_offset_map_[id] = timestamp_offset; |
| 1380 return true; | 1381 return true; |
| 1381 } | 1382 } |
| 1382 | 1383 |
| 1383 base::MessageLoop message_loop_; | 1384 base::MessageLoop message_loop_; |
| 1384 MockDemuxerHost host_; | 1385 MockDemuxerHost host_; |
| 1385 | 1386 |
| 1386 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | 1387 scoped_refptr<StrictMock<MockMediaLog>> media_log_; |
| 1387 | 1388 |
| 1388 scoped_ptr<ChunkDemuxer> demuxer_; | 1389 std::unique_ptr<ChunkDemuxer> demuxer_; |
| 1389 Demuxer::MediaTracksUpdatedCB init_segment_received_cb_; | 1390 Demuxer::MediaTracksUpdatedCB init_segment_received_cb_; |
| 1390 | 1391 |
| 1391 base::TimeDelta append_window_start_for_next_append_; | 1392 base::TimeDelta append_window_start_for_next_append_; |
| 1392 base::TimeDelta append_window_end_for_next_append_; | 1393 base::TimeDelta append_window_end_for_next_append_; |
| 1393 | 1394 |
| 1394 // Map of source id to timestamp offset to use for the next AppendData() | 1395 // Map of source id to timestamp offset to use for the next AppendData() |
| 1395 // operation for that source id. | 1396 // operation for that source id. |
| 1396 std::map<std::string, base::TimeDelta> timestamp_offset_map_; | 1397 std::map<std::string, base::TimeDelta> timestamp_offset_map_; |
| 1397 | 1398 |
| 1398 public: | 1399 public: |
| 1399 void InitSegmentReceived(scoped_ptr<MediaTracks> tracks) { | 1400 void InitSegmentReceived(std::unique_ptr<MediaTracks> tracks) { |
| 1400 DCHECK(tracks.get()); | 1401 DCHECK(tracks.get()); |
| 1401 DCHECK_GT(tracks->tracks().size(), 0u); | 1402 DCHECK_GT(tracks->tracks().size(), 0u); |
| 1402 | 1403 |
| 1403 InitSegmentReceivedMock(tracks); | 1404 InitSegmentReceivedMock(tracks); |
| 1404 } | 1405 } |
| 1405 | 1406 |
| 1406 private: | 1407 private: |
| 1407 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 1408 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
| 1408 }; | 1409 }; |
| 1409 | 1410 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1556 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 1557 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 1557 ASSERT_TRUE(audio_stream); | 1558 ASSERT_TRUE(audio_stream); |
| 1558 ASSERT_TRUE(video_stream); | 1559 ASSERT_TRUE(video_stream); |
| 1559 ASSERT_TRUE(text_stream); | 1560 ASSERT_TRUE(text_stream); |
| 1560 | 1561 |
| 1561 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23), | 1562 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23), |
| 1562 MuxedStreamInfo(kVideoTrackNum, "0K 30", 30), | 1563 MuxedStreamInfo(kVideoTrackNum, "0K 30", 30), |
| 1563 MuxedStreamInfo(kTextTrackNum, "10K")); | 1564 MuxedStreamInfo(kTextTrackNum, "10K")); |
| 1564 CheckExpectedRanges("{ [0,46) }"); | 1565 CheckExpectedRanges("{ [0,46) }"); |
| 1565 | 1566 |
| 1566 scoped_ptr<uint8_t[]> info_tracks; | 1567 std::unique_ptr<uint8_t[]> info_tracks; |
| 1567 int info_tracks_size = 0; | 1568 int info_tracks_size = 0; |
| 1568 CreateInitSegment( | 1569 CreateInitSegment( |
| 1569 HAS_TEXT | HAS_AUDIO | HAS_VIDEO | USE_ALTERNATE_TEXT_TRACK_ID, false, | 1570 HAS_TEXT | HAS_AUDIO | HAS_VIDEO | USE_ALTERNATE_TEXT_TRACK_ID, false, |
| 1570 false, &info_tracks, &info_tracks_size); | 1571 false, &info_tracks, &info_tracks_size); |
| 1571 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); | 1572 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
| 1572 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, | 1573 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, |
| 1573 append_window_start_for_next_append_, | 1574 append_window_start_for_next_append_, |
| 1574 append_window_end_for_next_append_, | 1575 append_window_end_for_next_append_, |
| 1575 ×tamp_offset_map_[kSourceId]); | 1576 ×tamp_offset_map_[kSourceId]); |
| 1576 | 1577 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1753 } | 1754 } |
| 1754 | 1755 |
| 1755 // Test the case where a Seek() is requested while the parser | 1756 // Test the case where a Seek() is requested while the parser |
| 1756 // is in the middle of cluster. This is to verify that the parser | 1757 // is in the middle of cluster. This is to verify that the parser |
| 1757 // does not reset itself on a seek. | 1758 // does not reset itself on a seek. |
| 1758 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) { | 1759 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) { |
| 1759 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1760 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 1760 | 1761 |
| 1761 InSequence s; | 1762 InSequence s; |
| 1762 | 1763 |
| 1763 scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6)); | 1764 std::unique_ptr<Cluster> cluster_a(GenerateCluster(0, 6)); |
| 1764 | 1765 |
| 1765 // Split the cluster into two appends at an arbitrary point near the end. | 1766 // Split the cluster into two appends at an arbitrary point near the end. |
| 1766 int first_append_size = cluster_a->size() - 11; | 1767 int first_append_size = cluster_a->size() - 11; |
| 1767 int second_append_size = cluster_a->size() - first_append_size; | 1768 int second_append_size = cluster_a->size() - first_append_size; |
| 1768 | 1769 |
| 1769 // Append the first part of the cluster. | 1770 // Append the first part of the cluster. |
| 1770 AppendData(cluster_a->data(), first_append_size); | 1771 AppendData(cluster_a->data(), first_append_size); |
| 1771 | 1772 |
| 1772 ExpectRead(DemuxerStream::AUDIO, 0); | 1773 ExpectRead(DemuxerStream::AUDIO, 0); |
| 1773 ExpectRead(DemuxerStream::VIDEO, 0); | 1774 ExpectRead(DemuxerStream::VIDEO, 0); |
| 1774 ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration); | 1775 ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration); |
| 1775 | 1776 |
| 1776 Seek(base::TimeDelta::FromSeconds(5)); | 1777 Seek(base::TimeDelta::FromSeconds(5)); |
| 1777 | 1778 |
| 1778 // Append the rest of the cluster. | 1779 // Append the rest of the cluster. |
| 1779 AppendData(cluster_a->data() + first_append_size, second_append_size); | 1780 AppendData(cluster_a->data() + first_append_size, second_append_size); |
| 1780 | 1781 |
| 1781 // Append the new cluster and verify that only the blocks | 1782 // Append the new cluster and verify that only the blocks |
| 1782 // in the new cluster are returned. | 1783 // in the new cluster are returned. |
| 1783 AppendCluster(GenerateCluster(5000, 6)); | 1784 AppendCluster(GenerateCluster(5000, 6)); |
| 1784 GenerateExpectedReads(5000, 6); | 1785 GenerateExpectedReads(5000, 6); |
| 1785 } | 1786 } |
| 1786 | 1787 |
| 1787 // Test the case where AppendData() is called before Init(). | 1788 // Test the case where AppendData() is called before Init(). |
| 1788 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { | 1789 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { |
| 1789 scoped_ptr<uint8_t[]> info_tracks; | 1790 std::unique_ptr<uint8_t[]> info_tracks; |
| 1790 int info_tracks_size = 0; | 1791 int info_tracks_size = 0; |
| 1791 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, | 1792 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, |
| 1792 false, false, &info_tracks, &info_tracks_size); | 1793 false, false, &info_tracks, &info_tracks_size); |
| 1793 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, | 1794 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, |
| 1794 append_window_start_for_next_append_, | 1795 append_window_start_for_next_append_, |
| 1795 append_window_end_for_next_append_, | 1796 append_window_end_for_next_append_, |
| 1796 ×tamp_offset_map_[kSourceId]); | 1797 ×tamp_offset_map_[kSourceId]); |
| 1797 } | 1798 } |
| 1798 | 1799 |
| 1799 // Make sure Read() callbacks are dispatched with the proper data. | 1800 // Make sure Read() callbacks are dispatched with the proper data. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1820 AppendCluster(kDefaultFirstCluster()); | 1821 AppendCluster(kDefaultFirstCluster()); |
| 1821 EXPECT_MEDIA_LOG(GeneratedSplice(13000, 10000)); | 1822 EXPECT_MEDIA_LOG(GeneratedSplice(13000, 10000)); |
| 1822 AppendCluster(GenerateCluster(10, 4)); | 1823 AppendCluster(GenerateCluster(10, 4)); |
| 1823 | 1824 |
| 1824 // Make sure that AppendCluster() does not fail with a cluster that has | 1825 // Make sure that AppendCluster() does not fail with a cluster that has |
| 1825 // overlaps with the previously appended cluster. | 1826 // overlaps with the previously appended cluster. |
| 1826 EXPECT_MEDIA_LOG(SkippingSpliceAlreadySpliced(0)); | 1827 EXPECT_MEDIA_LOG(SkippingSpliceAlreadySpliced(0)); |
| 1827 AppendCluster(GenerateCluster(5, 4)); | 1828 AppendCluster(GenerateCluster(5, 4)); |
| 1828 | 1829 |
| 1829 // Verify that AppendData() can still accept more data. | 1830 // Verify that AppendData() can still accept more data. |
| 1830 scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2)); | 1831 std::unique_ptr<Cluster> cluster_c(GenerateCluster(45, 2)); |
| 1831 EXPECT_MEDIA_LOG(GeneratedSplice(6000, 45000)); | 1832 EXPECT_MEDIA_LOG(GeneratedSplice(6000, 45000)); |
| 1832 demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size(), | 1833 demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size(), |
| 1833 append_window_start_for_next_append_, | 1834 append_window_start_for_next_append_, |
| 1834 append_window_end_for_next_append_, | 1835 append_window_end_for_next_append_, |
| 1835 ×tamp_offset_map_[kSourceId]); | 1836 ×tamp_offset_map_[kSourceId]); |
| 1836 } | 1837 } |
| 1837 | 1838 |
| 1838 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) { | 1839 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) { |
| 1839 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1840 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 1840 AppendCluster(kDefaultFirstCluster()); | 1841 AppendCluster(kDefaultFirstCluster()); |
| 1841 | 1842 |
| 1842 ClusterBuilder cb; | 1843 ClusterBuilder cb; |
| 1843 | 1844 |
| 1844 // Test the case where block timecodes are not monotonically | 1845 // Test the case where block timecodes are not monotonically |
| 1845 // increasing but stay above the cluster timecode. | 1846 // increasing but stay above the cluster timecode. |
| 1846 cb.SetClusterTimecode(5); | 1847 cb.SetClusterTimecode(5); |
| 1847 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 1848 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 1848 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 1849 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
| 1849 AddSimpleBlock(&cb, kAudioTrackNum, 7); | 1850 AddSimpleBlock(&cb, kAudioTrackNum, 7); |
| 1850 AddSimpleBlock(&cb, kVideoTrackNum, 15); | 1851 AddSimpleBlock(&cb, kVideoTrackNum, 15); |
| 1851 | 1852 |
| 1852 EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode()); | 1853 EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode()); |
| 1853 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 1854 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
| 1854 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); | 1855 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); |
| 1855 AppendCluster(cb.Finish()); | 1856 AppendCluster(cb.Finish()); |
| 1856 | 1857 |
| 1857 // Verify that AppendData() ignores data after the error. | 1858 // Verify that AppendData() ignores data after the error. |
| 1858 scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2)); | 1859 std::unique_ptr<Cluster> cluster_b(GenerateCluster(20, 2)); |
| 1859 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), | 1860 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), |
| 1860 append_window_start_for_next_append_, | 1861 append_window_start_for_next_append_, |
| 1861 append_window_end_for_next_append_, | 1862 append_window_end_for_next_append_, |
| 1862 ×tamp_offset_map_[kSourceId]); | 1863 ×tamp_offset_map_[kSourceId]); |
| 1863 } | 1864 } |
| 1864 | 1865 |
| 1865 TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) { | 1866 TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) { |
| 1866 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1867 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 1867 AppendCluster(kDefaultFirstCluster()); | 1868 AppendCluster(kDefaultFirstCluster()); |
| 1868 | 1869 |
| 1869 ClusterBuilder cb; | 1870 ClusterBuilder cb; |
| 1870 | 1871 |
| 1871 // Test timecodes going backwards and including values less than the cluster | 1872 // Test timecodes going backwards and including values less than the cluster |
| 1872 // timecode. | 1873 // timecode. |
| 1873 cb.SetClusterTimecode(5); | 1874 cb.SetClusterTimecode(5); |
| 1874 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 1875 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 1875 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 1876 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
| 1876 AddSimpleBlock(&cb, kAudioTrackNum, 3); | 1877 AddSimpleBlock(&cb, kAudioTrackNum, 3); |
| 1877 AddSimpleBlock(&cb, kVideoTrackNum, 3); | 1878 AddSimpleBlock(&cb, kVideoTrackNum, 3); |
| 1878 | 1879 |
| 1879 EXPECT_MEDIA_LOG(WebMNegativeTimecodeOffset("-2")); | 1880 EXPECT_MEDIA_LOG(WebMNegativeTimecodeOffset("-2")); |
| 1880 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 1881 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
| 1881 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); | 1882 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); |
| 1882 AppendCluster(cb.Finish()); | 1883 AppendCluster(cb.Finish()); |
| 1883 | 1884 |
| 1884 // Verify that AppendData() ignores data after the error. | 1885 // Verify that AppendData() ignores data after the error. |
| 1885 scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2)); | 1886 std::unique_ptr<Cluster> cluster_b(GenerateCluster(6, 2)); |
| 1886 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), | 1887 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), |
| 1887 append_window_start_for_next_append_, | 1888 append_window_start_for_next_append_, |
| 1888 append_window_end_for_next_append_, | 1889 append_window_end_for_next_append_, |
| 1889 ×tamp_offset_map_[kSourceId]); | 1890 ×tamp_offset_map_[kSourceId]); |
| 1890 } | 1891 } |
| 1891 | 1892 |
| 1892 | 1893 |
| 1893 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) { | 1894 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) { |
| 1894 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1895 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 1895 AppendCluster(kDefaultFirstCluster()); | 1896 AppendCluster(kDefaultFirstCluster()); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2175 } | 2176 } |
| 2176 | 2177 |
| 2177 // Make sure AppendData() will accept elements that span multiple calls. | 2178 // Make sure AppendData() will accept elements that span multiple calls. |
| 2178 TEST_F(ChunkDemuxerTest, AppendingInPieces) { | 2179 TEST_F(ChunkDemuxerTest, AppendingInPieces) { |
| 2179 EXPECT_CALL(*this, DemuxerOpened()); | 2180 EXPECT_CALL(*this, DemuxerOpened()); |
| 2180 demuxer_->Initialize( | 2181 demuxer_->Initialize( |
| 2181 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); | 2182 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
| 2182 | 2183 |
| 2183 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 2184 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 2184 | 2185 |
| 2185 scoped_ptr<uint8_t[]> info_tracks; | 2186 std::unique_ptr<uint8_t[]> info_tracks; |
| 2186 int info_tracks_size = 0; | 2187 int info_tracks_size = 0; |
| 2187 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, | 2188 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, |
| 2188 false, false, &info_tracks, &info_tracks_size); | 2189 false, false, &info_tracks, &info_tracks_size); |
| 2189 | 2190 |
| 2190 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 2191 std::unique_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
| 2191 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); | 2192 std::unique_ptr<Cluster> cluster_b(kDefaultSecondCluster()); |
| 2192 | 2193 |
| 2193 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); | 2194 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); |
| 2194 scoped_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); | 2195 std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); |
| 2195 uint8_t* dst = buffer.get(); | 2196 uint8_t* dst = buffer.get(); |
| 2196 memcpy(dst, info_tracks.get(), info_tracks_size); | 2197 memcpy(dst, info_tracks.get(), info_tracks_size); |
| 2197 dst += info_tracks_size; | 2198 dst += info_tracks_size; |
| 2198 | 2199 |
| 2199 memcpy(dst, cluster_a->data(), cluster_a->size()); | 2200 memcpy(dst, cluster_a->data(), cluster_a->size()); |
| 2200 dst += cluster_a->size(); | 2201 dst += cluster_a->size(); |
| 2201 | 2202 |
| 2202 memcpy(dst, cluster_b->data(), cluster_b->size()); | 2203 memcpy(dst, cluster_b->data(), cluster_b->size()); |
| 2203 dst += cluster_b->size(); | 2204 dst += cluster_b->size(); |
| 2204 | 2205 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2311 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); | 2312 ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO); |
| 2312 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); | 2313 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)); |
| 2313 ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps, | 2314 ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps, |
| 2314 base::TimeDelta::FromMilliseconds(2767))); | 2315 base::TimeDelta::FromMilliseconds(2767))); |
| 2315 } | 2316 } |
| 2316 | 2317 |
| 2317 // Verify that we output buffers before the entire cluster has been parsed. | 2318 // Verify that we output buffers before the entire cluster has been parsed. |
| 2318 TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) { | 2319 TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) { |
| 2319 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 2320 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 2320 | 2321 |
| 2321 scoped_ptr<Cluster> cluster(GenerateCluster(0, 6)); | 2322 std::unique_ptr<Cluster> cluster(GenerateCluster(0, 6)); |
| 2322 | 2323 |
| 2323 bool audio_read_done = false; | 2324 bool audio_read_done = false; |
| 2324 bool video_read_done = false; | 2325 bool video_read_done = false; |
| 2325 ReadAudio(base::Bind(&OnReadDone, | 2326 ReadAudio(base::Bind(&OnReadDone, |
| 2326 base::TimeDelta::FromMilliseconds(0), | 2327 base::TimeDelta::FromMilliseconds(0), |
| 2327 &audio_read_done)); | 2328 &audio_read_done)); |
| 2328 ReadVideo(base::Bind(&OnReadDone, | 2329 ReadVideo(base::Bind(&OnReadDone, |
| 2329 base::TimeDelta::FromMilliseconds(0), | 2330 base::TimeDelta::FromMilliseconds(0), |
| 2330 &video_read_done)); | 2331 &video_read_done)); |
| 2331 | 2332 |
| (...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3423 0, kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration)); | 3424 0, kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration)); |
| 3424 AppendCluster(video_id, GenerateSingleStreamCluster( | 3425 AppendCluster(video_id, GenerateSingleStreamCluster( |
| 3425 0, kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration)); | 3426 0, kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration)); |
| 3426 GenerateVideoStreamExpectedReads(27300, 4); | 3427 GenerateVideoStreamExpectedReads(27300, 4); |
| 3427 GenerateAudioStreamExpectedReads(27300, 4); | 3428 GenerateAudioStreamExpectedReads(27300, 4); |
| 3428 } | 3429 } |
| 3429 | 3430 |
| 3430 TEST_F(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) { | 3431 TEST_F(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) { |
| 3431 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 3432 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 3432 | 3433 |
| 3433 scoped_ptr<Cluster> cluster = GenerateCluster(0, 2); | 3434 std::unique_ptr<Cluster> cluster = GenerateCluster(0, 2); |
| 3434 // Append only part of the cluster data. | 3435 // Append only part of the cluster data. |
| 3435 AppendData(cluster->data(), cluster->size() - 13); | 3436 AppendData(cluster->data(), cluster->size() - 13); |
| 3436 | 3437 |
| 3437 // Confirm we're in the middle of parsing a media segment. | 3438 // Confirm we're in the middle of parsing a media segment. |
| 3438 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); | 3439 ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId)); |
| 3439 | 3440 |
| 3440 demuxer_->ResetParserState(kSourceId, | 3441 demuxer_->ResetParserState(kSourceId, |
| 3441 append_window_start_for_next_append_, | 3442 append_window_start_for_next_append_, |
| 3442 append_window_end_for_next_append_, | 3443 append_window_end_for_next_append_, |
| 3443 ×tamp_offset_map_[kSourceId]); | 3444 ×tamp_offset_map_[kSourceId]); |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4367 | 4368 |
| 4368 // A new cluster indicates end of the previous cluster with unknown size. | 4369 // A new cluster indicates end of the previous cluster with unknown size. |
| 4369 AppendCluster(GenerateCluster(46, 66, 5, true)); | 4370 AppendCluster(GenerateCluster(46, 66, 5, true)); |
| 4370 CheckExpectedRanges("{ [0,115) }"); | 4371 CheckExpectedRanges("{ [0,115) }"); |
| 4371 } | 4372 } |
| 4372 | 4373 |
| 4373 TEST_F(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) { | 4374 TEST_F(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) { |
| 4374 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 4375 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 4375 | 4376 |
| 4376 // Add two clusters separated by Cues in a single Append() call. | 4377 // Add two clusters separated by Cues in a single Append() call. |
| 4377 scoped_ptr<Cluster> cluster = GenerateCluster(0, 0, 4, true); | 4378 std::unique_ptr<Cluster> cluster = GenerateCluster(0, 0, 4, true); |
| 4378 std::vector<uint8_t> data(cluster->data(), cluster->data() + cluster->size()); | 4379 std::vector<uint8_t> data(cluster->data(), cluster->data() + cluster->size()); |
| 4379 data.insert(data.end(), kCuesHeader, kCuesHeader + sizeof(kCuesHeader)); | 4380 data.insert(data.end(), kCuesHeader, kCuesHeader + sizeof(kCuesHeader)); |
| 4380 cluster = GenerateCluster(46, 66, 5, true); | 4381 cluster = GenerateCluster(46, 66, 5, true); |
| 4381 data.insert(data.end(), cluster->data(), cluster->data() + cluster->size()); | 4382 data.insert(data.end(), cluster->data(), cluster->data() + cluster->size()); |
| 4382 AppendData(&*data.begin(), data.size()); | 4383 AppendData(&*data.begin(), data.size()); |
| 4383 | 4384 |
| 4384 CheckExpectedRanges("{ [0,115) }"); | 4385 CheckExpectedRanges("{ [0,115) }"); |
| 4385 } | 4386 } |
| 4386 | 4387 |
| 4387 TEST_F(ChunkDemuxerTest, CuesBetweenClusters) { | 4388 TEST_F(ChunkDemuxerTest, CuesBetweenClusters) { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4632 // A: [K K K K K K] | 4633 // A: [K K K K K K] |
| 4633 // V [..............K n] | 4634 // V [..............K n] |
| 4634 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 4635 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 4635 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 4636 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 4636 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 4637 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 4637 | 4638 |
| 4638 std::vector<MuxedStreamInfo> msi(2); | 4639 std::vector<MuxedStreamInfo> msi(2); |
| 4639 msi[0] = | 4640 msi[0] = |
| 4640 MuxedStreamInfo(kAudioTrackNum, "0K 10K 20K 30K 40K 50K 60K 70K 80D10K"); | 4641 MuxedStreamInfo(kAudioTrackNum, "0K 10K 20K 30K 40K 50K 60K 70K 80D10K"); |
| 4641 msi[1] = MuxedStreamInfo(kVideoTrackNum, "31 41 51 61 71K 81", 10); | 4642 msi[1] = MuxedStreamInfo(kVideoTrackNum, "31 41 51 61 71K 81", 10); |
| 4642 scoped_ptr<Cluster> cluster = GenerateMuxedCluster(msi); | 4643 std::unique_ptr<Cluster> cluster = GenerateMuxedCluster(msi); |
| 4643 | 4644 |
| 4644 // Append the first part of the cluster, up to the beginning of the first | 4645 // Append the first part of the cluster, up to the beginning of the first |
| 4645 // video simpleblock. The result should be just 4 audio blocks and no video | 4646 // video simpleblock. The result should be just 4 audio blocks and no video |
| 4646 // blocks are appended. Since the stream parser does not yet have a duration | 4647 // blocks are appended. Since the stream parser does not yet have a duration |
| 4647 // for the 4th audio block in this partial cluster append, it is not yet | 4648 // for the 4th audio block in this partial cluster append, it is not yet |
| 4648 // emitted from the parser, and only the first 3 audio blocks are expected to | 4649 // emitted from the parser, and only the first 3 audio blocks are expected to |
| 4649 // be buffered by and available from the demuxer. | 4650 // be buffered by and available from the demuxer. |
| 4650 ASSERT_EQ(kVideoTrackNum, 1); | 4651 ASSERT_EQ(kVideoTrackNum, 1); |
| 4651 int video_start = 0; | 4652 int video_start = 0; |
| 4652 bool found = false; | 4653 bool found = false; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 4675 cluster->size() - video_start); | 4676 cluster->size() - video_start); |
| 4676 | 4677 |
| 4677 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); | 4678 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); |
| 4678 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); | 4679 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); |
| 4679 CheckExpectedRanges("{ [30,90) }"); | 4680 CheckExpectedRanges("{ [30,90) }"); |
| 4680 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); | 4681 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); |
| 4681 CheckExpectedBuffers(video_stream, "71K 81"); | 4682 CheckExpectedBuffers(video_stream, "71K 81"); |
| 4682 } | 4683 } |
| 4683 | 4684 |
| 4684 } // namespace media | 4685 } // namespace media |
| OLD | NEW |