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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "media/base/audio_decoder_config.h" | 6 #include "media/base/audio_decoder_config.h" |
| 7 #include "media/base/decoder_buffer.h" |
7 #include "media/base/mock_callback.h" | 8 #include "media/base/mock_callback.h" |
8 #include "media/base/mock_demuxer_host.h" | 9 #include "media/base/mock_demuxer_host.h" |
9 #include "media/base/test_data_util.h" | 10 #include "media/base/test_data_util.h" |
10 #include "media/filters/chunk_demuxer.h" | 11 #include "media/filters/chunk_demuxer.h" |
11 #include "media/filters/chunk_demuxer_client.h" | 12 #include "media/filters/chunk_demuxer_client.h" |
12 #include "media/webm/cluster_builder.h" | 13 #include "media/webm/cluster_builder.h" |
13 #include "media/webm/webm_constants.h" | 14 #include "media/webm/webm_constants.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
15 | 16 |
16 using ::testing::AnyNumber; | 17 using ::testing::AnyNumber; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 } | 64 } |
64 } | 65 } |
65 | 66 |
66 MATCHER_P(HasTimestamp, timestamp_in_ms, "") { | 67 MATCHER_P(HasTimestamp, timestamp_in_ms, "") { |
67 return arg && !arg->IsEndOfStream() && | 68 return arg && !arg->IsEndOfStream() && |
68 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms; | 69 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms; |
69 } | 70 } |
70 | 71 |
71 static void OnReadDone(const base::TimeDelta& expected_time, | 72 static void OnReadDone(const base::TimeDelta& expected_time, |
72 bool* called, | 73 bool* called, |
73 const scoped_refptr<Buffer>& buffer) { | 74 const scoped_refptr<DecoderBuffer>& buffer) { |
74 EXPECT_EQ(expected_time, buffer->GetTimestamp()); | 75 EXPECT_EQ(expected_time, buffer->GetTimestamp()); |
75 *called = true; | 76 *called = true; |
76 } | 77 } |
77 | 78 |
78 class MockChunkDemuxerClient : public ChunkDemuxerClient { | 79 class MockChunkDemuxerClient : public ChunkDemuxerClient { |
79 public: | 80 public: |
80 MockChunkDemuxerClient() {} | 81 MockChunkDemuxerClient() {} |
81 virtual ~MockChunkDemuxerClient() {} | 82 virtual ~MockChunkDemuxerClient() {} |
82 | 83 |
83 MOCK_METHOD1(DemuxerOpened, void(ChunkDemuxer* demuxer)); | 84 MOCK_METHOD1(DemuxerOpened, void(ChunkDemuxer* demuxer)); |
(...skipping 24 matching lines...) Expand all Loading... |
108 demuxer_(new ChunkDemuxer(client_.get())) { | 109 demuxer_(new ChunkDemuxer(client_.get())) { |
109 } | 110 } |
110 | 111 |
111 virtual ~ChunkDemuxerTest() { | 112 virtual ~ChunkDemuxerTest() { |
112 ShutdownDemuxer(); | 113 ShutdownDemuxer(); |
113 } | 114 } |
114 | 115 |
115 void CreateInfoTracks(bool has_audio, bool has_video, | 116 void CreateInfoTracks(bool has_audio, bool has_video, |
116 bool video_content_encoded, scoped_array<uint8>* buffer, | 117 bool video_content_encoded, scoped_array<uint8>* buffer, |
117 int* size) { | 118 int* size) { |
118 scoped_array<uint8> info; | 119 scoped_refptr<DecoderBuffer> info; |
119 int info_size = 0; | 120 scoped_refptr<DecoderBuffer> audio_track_entry; |
120 scoped_array<uint8> audio_track_entry; | 121 scoped_refptr<DecoderBuffer> video_track_entry; |
121 int audio_track_entry_size = 0; | 122 scoped_refptr<DecoderBuffer> video_content_encodings; |
122 scoped_array<uint8> video_track_entry; | |
123 int video_track_entry_size = 0; | |
124 scoped_array<uint8> video_content_encodings; | |
125 int video_content_encodings_size = 0; | |
126 | 123 |
127 ReadTestDataFile("webm_info_element", &info, &info_size); | 124 info = ReadTestDataFile("webm_info_element"); |
128 | 125 |
129 int tracks_element_size = 0; | 126 int tracks_element_size = 0; |
130 | 127 |
131 if (has_audio) { | 128 if (has_audio) { |
132 ReadTestDataFile("webm_vorbis_track_entry", &audio_track_entry, | 129 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); |
133 &audio_track_entry_size); | 130 tracks_element_size += audio_track_entry->GetDataSize(); |
134 tracks_element_size += audio_track_entry_size; | |
135 } | 131 } |
136 | 132 |
137 if (has_video) { | 133 if (has_video) { |
138 ReadTestDataFile("webm_vp8_track_entry", &video_track_entry, | 134 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); |
139 &video_track_entry_size); | 135 tracks_element_size += video_track_entry->GetDataSize(); |
140 tracks_element_size += video_track_entry_size; | |
141 if (video_content_encoded) { | 136 if (video_content_encoded) { |
142 ReadTestDataFile("webm_content_encodings", &video_content_encodings, | 137 video_content_encodings = ReadTestDataFile("webm_content_encodings"); |
143 &video_content_encodings_size); | 138 tracks_element_size += video_content_encodings->GetDataSize(); |
144 tracks_element_size += video_content_encodings_size; | |
145 } | 139 } |
146 } | 140 } |
147 | 141 |
148 *size = info_size + kTracksHeaderSize + tracks_element_size; | 142 *size = info->GetDataSize() + kTracksHeaderSize + tracks_element_size; |
149 | 143 |
150 buffer->reset(new uint8[*size]); | 144 buffer->reset(new uint8[*size]); |
151 | 145 |
152 uint8* buf = buffer->get(); | 146 uint8* buf = buffer->get(); |
153 memcpy(buf, info.get(), info_size); | 147 memcpy(buf, info->GetData(), info->GetDataSize()); |
154 buf += info_size; | 148 buf += info->GetDataSize(); |
155 | 149 |
156 memcpy(buf, kTracksHeader, kTracksHeaderSize); | 150 memcpy(buf, kTracksHeader, kTracksHeaderSize); |
157 WriteInt64(buf + kTracksSizeOffset, tracks_element_size); | 151 WriteInt64(buf + kTracksSizeOffset, tracks_element_size); |
158 buf += kTracksHeaderSize; | 152 buf += kTracksHeaderSize; |
159 | 153 |
160 if (has_audio) { | 154 if (has_audio) { |
161 memcpy(buf, audio_track_entry.get(), audio_track_entry_size); | 155 memcpy(buf, audio_track_entry->GetData(), |
162 buf += audio_track_entry_size; | 156 audio_track_entry->GetDataSize()); |
| 157 buf += audio_track_entry->GetDataSize(); |
163 } | 158 } |
164 | 159 |
165 if (has_video) { | 160 if (has_video) { |
166 memcpy(buf, video_track_entry.get(), video_track_entry_size); | 161 memcpy(buf, video_track_entry->GetData(), |
| 162 video_track_entry->GetDataSize()); |
167 if (video_content_encoded) { | 163 if (video_content_encoded) { |
168 memcpy(buf + video_track_entry_size, video_content_encodings.get(), | 164 memcpy(buf + video_track_entry->GetDataSize(), |
169 video_content_encodings_size); | 165 video_content_encodings->GetData(), |
170 video_track_entry_size += video_content_encodings_size; | 166 video_content_encodings->GetDataSize()); |
171 WriteInt64(buf + kVideoTrackSizeOffset, | 167 WriteInt64(buf + kVideoTrackSizeOffset, |
172 video_track_entry_size - kVideoTrackEntryHeaderSize); | 168 video_track_entry->GetDataSize() + |
| 169 video_content_encodings->GetDataSize() - |
| 170 kVideoTrackEntryHeaderSize); |
| 171 buf += video_content_encodings->GetDataSize(); |
173 } | 172 } |
174 buf += video_track_entry_size; | 173 buf += video_track_entry->GetDataSize(); |
175 } | 174 } |
176 } | 175 } |
177 | 176 |
178 ChunkDemuxer::Status AddId() { | 177 ChunkDemuxer::Status AddId() { |
179 std::vector<std::string> codecs(2); | 178 std::vector<std::string> codecs(2); |
180 codecs[0] = "vp8"; | 179 codecs[0] = "vp8"; |
181 codecs[1] = "vorbis"; | 180 codecs[1] = "vorbis"; |
182 return demuxer_->AddId(kSourceId, "video/webm", codecs); | 181 return demuxer_->AddId(kSourceId, "video/webm", codecs); |
183 } | 182 } |
184 | 183 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 ExpectRead(audio, audio_timecode); | 332 ExpectRead(audio, audio_timecode); |
334 audio_timecode += kAudioBlockDuration; | 333 audio_timecode += kAudioBlockDuration; |
335 continue; | 334 continue; |
336 } | 335 } |
337 | 336 |
338 ExpectRead(video, video_timecode); | 337 ExpectRead(video, video_timecode); |
339 video_timecode += kVideoBlockDuration; | 338 video_timecode += kVideoBlockDuration; |
340 } | 339 } |
341 } | 340 } |
342 | 341 |
343 MOCK_METHOD1(ReadDone, void(const scoped_refptr<Buffer>&)); | 342 MOCK_METHOD1(ReadDone, void(const scoped_refptr<DecoderBuffer>&)); |
344 | 343 |
345 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { | 344 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { |
346 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); | 345 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); |
347 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, | 346 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, |
348 base::Unretained(this))); | 347 base::Unretained(this))); |
349 } | 348 } |
350 | 349 |
351 MOCK_METHOD1(Checkpoint, void(int id)); | 350 MOCK_METHOD1(Checkpoint, void(int id)); |
352 | 351 |
353 struct BufferTimestamps { | 352 struct BufferTimestamps { |
354 int video_time_ms; | 353 int video_time_ms; |
355 int audio_time_ms; | 354 int audio_time_ms; |
356 }; | 355 }; |
357 static const int kSkip = -1; | 356 static const int kSkip = -1; |
358 | 357 |
359 // Test parsing a WebM file. | 358 // Test parsing a WebM file. |
360 // |filename| - The name of the file in media/test/data to parse. | 359 // |filename| - The name of the file in media/test/data to parse. |
361 // |timestamps| - The expected timestamps on the parsed buffers. | 360 // |timestamps| - The expected timestamps on the parsed buffers. |
362 // a timestamp of kSkip indicates that a Read() call for that stream | 361 // a timestamp of kSkip indicates that a Read() call for that stream |
363 // shouldn't be made on that iteration of the loop. If both streams have | 362 // shouldn't be made on that iteration of the loop. If both streams have |
364 // a kSkip then the loop will terminate. | 363 // a kSkip then the loop will terminate. |
365 bool ParseWebMFile(const std::string& filename, | 364 bool ParseWebMFile(const std::string& filename, |
366 const BufferTimestamps* timestamps, | 365 const BufferTimestamps* timestamps, |
367 const base::TimeDelta& duration) { | 366 const base::TimeDelta& duration) { |
368 scoped_array<uint8> buffer; | |
369 int buffer_size = 0; | |
370 | |
371 EXPECT_CALL(*client_, DemuxerOpened(_)); | 367 EXPECT_CALL(*client_, DemuxerOpened(_)); |
372 demuxer_->Initialize( | 368 demuxer_->Initialize( |
373 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); | 369 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); |
374 | 370 |
375 if (AddId() != ChunkDemuxer::kOk) | 371 if (AddId() != ChunkDemuxer::kOk) |
376 return false; | 372 return false; |
377 | 373 |
378 // Read a WebM file into memory and send the data to the demuxer. | 374 // Read a WebM file into memory and send the data to the demuxer. |
379 ReadTestDataFile(filename, &buffer, &buffer_size); | 375 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
380 if (!AppendDataInPieces(buffer.get(), buffer_size, 512)) | 376 if (!AppendDataInPieces(buffer->GetData(), buffer->GetDataSize(), 512)) |
381 return false; | 377 return false; |
382 | 378 |
383 scoped_refptr<DemuxerStream> audio = | 379 scoped_refptr<DemuxerStream> audio = |
384 demuxer_->GetStream(DemuxerStream::AUDIO); | 380 demuxer_->GetStream(DemuxerStream::AUDIO); |
385 scoped_refptr<DemuxerStream> video = | 381 scoped_refptr<DemuxerStream> video = |
386 demuxer_->GetStream(DemuxerStream::VIDEO); | 382 demuxer_->GetStream(DemuxerStream::VIDEO); |
387 | 383 |
388 // Verify that the timestamps on the first few packets match what we | 384 // Verify that the timestamps on the first few packets match what we |
389 // expect. | 385 // expect. |
390 for (size_t i = 0; | 386 for (size_t i = 0; |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 } | 763 } |
768 | 764 |
769 // Check to see if |audio_read_done_| and |video_read_done_| variables | 765 // Check to see if |audio_read_done_| and |video_read_done_| variables |
770 // match |expected|. | 766 // match |expected|. |
771 void CheckIfReadDonesWereCalled(bool expected) { | 767 void CheckIfReadDonesWereCalled(bool expected) { |
772 EXPECT_EQ(expected, audio_read_done_); | 768 EXPECT_EQ(expected, audio_read_done_); |
773 EXPECT_EQ(expected, video_read_done_); | 769 EXPECT_EQ(expected, video_read_done_); |
774 } | 770 } |
775 | 771 |
776 private: | 772 private: |
777 static void OnEndOfStreamReadDone(bool* called, | 773 static void OnEndOfStreamReadDone( |
778 const scoped_refptr<Buffer>& buffer) { | 774 bool* called, const scoped_refptr<DecoderBuffer>& buffer) { |
779 EXPECT_TRUE(buffer->IsEndOfStream()); | 775 EXPECT_TRUE(buffer->IsEndOfStream()); |
780 *called = true; | 776 *called = true; |
781 } | 777 } |
782 | 778 |
783 scoped_refptr<Demuxer> demuxer_; | 779 scoped_refptr<Demuxer> demuxer_; |
784 bool audio_read_done_; | 780 bool audio_read_done_; |
785 bool video_read_done_; | 781 bool video_read_done_; |
786 | 782 |
787 DISALLOW_COPY_AND_ASSIGN(EndOfStreamHelper); | 783 DISALLOW_COPY_AND_ASSIGN(EndOfStreamHelper); |
788 }; | 784 }; |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 | 1071 |
1076 std::vector<std::string> codecs(1); | 1072 std::vector<std::string> codecs(1); |
1077 codecs[0] = "vp8"; | 1073 codecs[0] = "vp8"; |
1078 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1074 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
1079 ChunkDemuxer::kOk); | 1075 ChunkDemuxer::kOk); |
1080 | 1076 |
1081 ASSERT_TRUE(AppendInfoTracks(true, true, false)); | 1077 ASSERT_TRUE(AppendInfoTracks(true, true, false)); |
1082 } | 1078 } |
1083 | 1079 |
1084 } // namespace media | 1080 } // namespace media |
OLD | NEW |