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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 | 57 |
58 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at | 58 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at |
59 // index 1 and spans 8 bytes. | 59 // index 1 and spans 8 bytes. |
60 static const int kVideoTrackSizeOffset = 1; | 60 static const int kVideoTrackSizeOffset = 1; |
61 static const int kVideoTrackSizeWidth = 8; | 61 static const int kVideoTrackSizeWidth = 8; |
62 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + | 62 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + |
63 kVideoTrackSizeWidth; | 63 kVideoTrackSizeWidth; |
64 | 64 |
65 static const int kVideoTrackNum = 1; | 65 static const int kVideoTrackNum = 1; |
66 static const int kAudioTrackNum = 2; | 66 static const int kAudioTrackNum = 2; |
67 static const int kTextTrackNum = 3; | |
67 | 68 |
68 static const int kAudioBlockDuration = 23; | 69 static const int kAudioBlockDuration = 23; |
69 static const int kVideoBlockDuration = 33; | 70 static const int kVideoBlockDuration = 33; |
70 static const int kBlockSize = 10; | 71 static const int kBlockSize = 10; |
71 | 72 |
72 static const char kSourceId[] = "SourceId"; | 73 static const char kSourceId[] = "SourceId"; |
73 static const char kDefaultFirstClusterRange[] = "{ [0,46) }"; | 74 static const char kDefaultFirstClusterRange[] = "{ [0,46) }"; |
74 static const int kDefaultFirstClusterEndTimestamp = 66; | 75 static const int kDefaultFirstClusterEndTimestamp = 66; |
75 static const int kDefaultSecondClusterEndTimestamp = 132; | 76 static const int kDefaultSecondClusterEndTimestamp = 132; |
76 | 77 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 | 153 |
153 ChunkDemuxerTest() { | 154 ChunkDemuxerTest() { |
154 CreateNewDemuxer(); | 155 CreateNewDemuxer(); |
155 } | 156 } |
156 | 157 |
157 void CreateNewDemuxer() { | 158 void CreateNewDemuxer() { |
158 base::Closure open_cb = | 159 base::Closure open_cb = |
159 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); | 160 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
160 Demuxer::NeedKeyCB need_key_cb = | 161 Demuxer::NeedKeyCB need_key_cb = |
161 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); | 162 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); |
162 AddTextTrackCB add_text_track_cb = | 163 demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, LogCB())); |
163 base::Bind(&ChunkDemuxerTest::OnTextTrack, base::Unretained(this)); | |
164 demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, | |
165 add_text_track_cb, LogCB())); | |
166 } | 164 } |
167 | 165 |
168 virtual ~ChunkDemuxerTest() { | 166 virtual ~ChunkDemuxerTest() { |
169 ShutdownDemuxer(); | 167 ShutdownDemuxer(); |
170 } | 168 } |
171 | 169 |
172 void CreateInitSegment(bool has_audio, bool has_video, | 170 void CreateInitSegment(bool has_audio, bool has_video, bool has_text, |
173 bool is_audio_encrypted, bool is_video_encrypted, | 171 bool is_audio_encrypted, bool is_video_encrypted, |
174 scoped_ptr<uint8[]>* buffer, | 172 scoped_ptr<uint8[]>* buffer, |
175 int* size) { | 173 int* size) { |
176 scoped_refptr<DecoderBuffer> ebml_header; | 174 scoped_refptr<DecoderBuffer> ebml_header; |
177 scoped_refptr<DecoderBuffer> info; | 175 scoped_refptr<DecoderBuffer> info; |
178 scoped_refptr<DecoderBuffer> audio_track_entry; | 176 scoped_refptr<DecoderBuffer> audio_track_entry; |
179 scoped_refptr<DecoderBuffer> video_track_entry; | 177 scoped_refptr<DecoderBuffer> video_track_entry; |
180 scoped_refptr<DecoderBuffer> audio_content_encodings; | 178 scoped_refptr<DecoderBuffer> audio_content_encodings; |
181 scoped_refptr<DecoderBuffer> video_content_encodings; | 179 scoped_refptr<DecoderBuffer> video_content_encodings; |
180 scoped_refptr<DecoderBuffer> text_track_entry; | |
182 | 181 |
183 ebml_header = ReadTestDataFile("webm_ebml_element"); | 182 ebml_header = ReadTestDataFile("webm_ebml_element"); |
184 | 183 |
185 info = ReadTestDataFile("webm_info_element"); | 184 info = ReadTestDataFile("webm_info_element"); |
186 | 185 |
187 int tracks_element_size = 0; | 186 int tracks_element_size = 0; |
188 | 187 |
189 if (has_audio) { | 188 if (has_audio) { |
190 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); | 189 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); |
191 tracks_element_size += audio_track_entry->data_size(); | 190 tracks_element_size += audio_track_entry->data_size(); |
192 if (is_audio_encrypted) { | 191 if (is_audio_encrypted) { |
193 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); | 192 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); |
194 tracks_element_size += audio_content_encodings->data_size(); | 193 tracks_element_size += audio_content_encodings->data_size(); |
195 } | 194 } |
196 } | 195 } |
197 | 196 |
198 if (has_video) { | 197 if (has_video) { |
199 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); | 198 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); |
200 tracks_element_size += video_track_entry->data_size(); | 199 tracks_element_size += video_track_entry->data_size(); |
201 if (is_video_encrypted) { | 200 if (is_video_encrypted) { |
202 video_content_encodings = ReadTestDataFile("webm_content_encodings"); | 201 video_content_encodings = ReadTestDataFile("webm_content_encodings"); |
203 tracks_element_size += video_content_encodings->data_size(); | 202 tracks_element_size += video_content_encodings->data_size(); |
204 } | 203 } |
205 } | 204 } |
206 | 205 |
206 if (has_text) { | |
207 // TODO(matthewjheaney): create an abstraction to do this. | |
acolwell GONE FROM CHROMIUM
2013/11/20 01:15:24
File a bug to track this and add the crbug url her
Matthew Heaney (Chromium)
2013/11/20 19:23:16
Created CR:
https://code.google.com/p/chromium/iss
| |
208 // We need it to also handle the creation of multiple text tracks. | |
209 // | |
210 // This is the track entry for a text track, | |
211 // TrackEntry [AE], size=26 | |
212 // TrackNum [D7], size=1, val=3 | |
213 // TrackType [83], size=1, val=0x11 | |
214 // CodecId [86], size=18, val="D_WEBVTT/SUBTITLES" | |
215 const char str[] = "\xAE\x9A\xD7\x81\x03\x83\x81\x11\x86\x92" | |
216 "D_WEBVTT/SUBTITLES"; | |
217 const int len = strlen(str); | |
218 DCHECK_EQ(len, 28); | |
219 const uint8* const buf = reinterpret_cast<const uint8*>(str); | |
220 text_track_entry = DecoderBuffer::CopyFrom(buf, len); | |
221 tracks_element_size += text_track_entry->data_size(); | |
222 } | |
223 | |
207 *size = ebml_header->data_size() + info->data_size() + | 224 *size = ebml_header->data_size() + info->data_size() + |
208 kTracksHeaderSize + tracks_element_size; | 225 kTracksHeaderSize + tracks_element_size; |
209 | 226 |
210 buffer->reset(new uint8[*size]); | 227 buffer->reset(new uint8[*size]); |
211 | 228 |
212 uint8* buf = buffer->get(); | 229 uint8* buf = buffer->get(); |
213 memcpy(buf, ebml_header->data(), ebml_header->data_size()); | 230 memcpy(buf, ebml_header->data(), ebml_header->data_size()); |
214 buf += ebml_header->data_size(); | 231 buf += ebml_header->data_size(); |
215 | 232 |
216 memcpy(buf, info->data(), info->data_size()); | 233 memcpy(buf, info->data(), info->data_size()); |
(...skipping 29 matching lines...) Expand all Loading... | |
246 video_content_encodings->data(), | 263 video_content_encodings->data(), |
247 video_content_encodings->data_size()); | 264 video_content_encodings->data_size()); |
248 WriteInt64(buf + kVideoTrackSizeOffset, | 265 WriteInt64(buf + kVideoTrackSizeOffset, |
249 video_track_entry->data_size() + | 266 video_track_entry->data_size() + |
250 video_content_encodings->data_size() - | 267 video_content_encodings->data_size() - |
251 kVideoTrackEntryHeaderSize); | 268 kVideoTrackEntryHeaderSize); |
252 buf += video_content_encodings->data_size(); | 269 buf += video_content_encodings->data_size(); |
253 } | 270 } |
254 buf += video_track_entry->data_size(); | 271 buf += video_track_entry->data_size(); |
255 } | 272 } |
273 | |
274 if (has_text) { | |
275 memcpy(buf, text_track_entry->data(), | |
276 text_track_entry->data_size()); | |
277 buf += text_track_entry->data_size(); | |
278 } | |
256 } | 279 } |
257 | 280 |
258 ChunkDemuxer::Status AddId() { | 281 ChunkDemuxer::Status AddId() { |
259 return AddId(kSourceId, true, true); | 282 return AddId(kSourceId, true, true); |
260 } | 283 } |
261 | 284 |
262 ChunkDemuxer::Status AddId(const std::string& source_id, | 285 ChunkDemuxer::Status AddId(const std::string& source_id, |
263 bool has_audio, bool has_video) { | 286 bool has_audio, bool has_video) { |
264 std::vector<std::string> codecs; | 287 std::vector<std::string> codecs; |
265 std::string type; | 288 std::string type; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 const uint8* end = data + length; | 381 const uint8* end = data + length; |
359 while (start < end) { | 382 while (start < end) { |
360 size_t append_size = std::min(piece_size, | 383 size_t append_size = std::min(piece_size, |
361 static_cast<size_t>(end - start)); | 384 static_cast<size_t>(end - start)); |
362 AppendData(start, append_size); | 385 AppendData(start, append_size); |
363 start += append_size; | 386 start += append_size; |
364 } | 387 } |
365 } | 388 } |
366 | 389 |
367 void AppendInitSegment(bool has_audio, bool has_video) { | 390 void AppendInitSegment(bool has_audio, bool has_video) { |
368 AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video); | 391 AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video, false); |
392 } | |
393 | |
394 void AppendInitSegmentText(bool has_audio, bool has_video) { | |
395 AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video, true); | |
369 } | 396 } |
370 | 397 |
371 void AppendInitSegmentWithSourceId(const std::string& source_id, | 398 void AppendInitSegmentWithSourceId(const std::string& source_id, |
372 bool has_audio, bool has_video) { | 399 bool has_audio, bool has_video, |
400 bool has_text) { | |
373 AppendInitSegmentWithEncryptedInfo( | 401 AppendInitSegmentWithEncryptedInfo( |
374 source_id, has_audio, has_video, false, false); | 402 source_id, has_audio, has_video, has_text, false, false); |
375 } | 403 } |
376 | 404 |
377 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, | 405 void AppendInitSegmentWithEncryptedInfo(const std::string& source_id, |
378 bool has_audio, bool has_video, | 406 bool has_audio, bool has_video, |
407 bool has_text, | |
379 bool is_audio_encrypted, | 408 bool is_audio_encrypted, |
380 bool is_video_encrypted) { | 409 bool is_video_encrypted) { |
381 scoped_ptr<uint8[]> info_tracks; | 410 scoped_ptr<uint8[]> info_tracks; |
382 int info_tracks_size = 0; | 411 int info_tracks_size = 0; |
383 CreateInitSegment(has_audio, has_video, | 412 CreateInitSegment(has_audio, has_video, has_text, |
384 is_audio_encrypted, is_video_encrypted, | 413 is_audio_encrypted, is_video_encrypted, |
385 &info_tracks, &info_tracks_size); | 414 &info_tracks, &info_tracks_size); |
386 AppendData(source_id, info_tracks.get(), info_tracks_size); | 415 AppendData(source_id, info_tracks.get(), info_tracks_size); |
387 } | 416 } |
388 | 417 |
389 void AppendGarbage() { | 418 void AppendGarbage() { |
390 // Fill up an array with gibberish. | 419 // Fill up an array with gibberish. |
391 int garbage_cluster_size = 10; | 420 int garbage_cluster_size = 10; |
392 scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]); | 421 scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]); |
393 for (int i = 0; i < garbage_cluster_size; ++i) | 422 for (int i = 0; i < garbage_cluster_size; ++i) |
(...skipping 17 matching lines...) Expand all Loading... | |
411 return CreateInitDoneCB(expected_status); | 440 return CreateInitDoneCB(expected_status); |
412 } | 441 } |
413 | 442 |
414 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { | 443 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { |
415 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 444 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, |
416 base::Unretained(this), | 445 base::Unretained(this), |
417 expected_status); | 446 expected_status); |
418 } | 447 } |
419 | 448 |
420 bool InitDemuxer(bool has_audio, bool has_video) { | 449 bool InitDemuxer(bool has_audio, bool has_video) { |
421 return InitDemuxerWithEncryptionInfo(has_audio, has_video, false, false); | 450 return InitDemuxerWithEncryptionInfo(has_audio, has_video, false, |
451 false, false); | |
452 } | |
453 | |
454 bool InitDemuxerText(bool has_audio, bool has_video) { | |
455 return InitDemuxerWithEncryptionInfo(has_audio, has_video, true, | |
456 false, false); | |
422 } | 457 } |
423 | 458 |
424 bool InitDemuxerWithEncryptionInfo( | 459 bool InitDemuxerWithEncryptionInfo( |
425 bool has_audio, bool has_video, | 460 bool has_audio, bool has_video, bool has_text, |
426 bool is_audio_encrypted, bool is_video_encrypted) { | 461 bool is_audio_encrypted, bool is_video_encrypted) { |
427 PipelineStatus expected_status = | 462 PipelineStatus expected_status = |
428 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; | 463 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; |
429 | 464 |
430 base::TimeDelta expected_duration = kNoTimestamp(); | 465 base::TimeDelta expected_duration = kNoTimestamp(); |
431 if (expected_status == PIPELINE_OK) | 466 if (expected_status == PIPELINE_OK) |
432 expected_duration = kDefaultDuration(); | 467 expected_duration = kDefaultDuration(); |
433 | 468 |
434 EXPECT_CALL(*this, DemuxerOpened()); | 469 EXPECT_CALL(*this, DemuxerOpened()); |
435 demuxer_->Initialize( | 470 demuxer_->Initialize( |
436 &host_, CreateInitDoneCB(expected_duration, expected_status)); | 471 &host_, CreateInitDoneCB(expected_duration, expected_status), true); |
437 | 472 |
438 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 473 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) |
439 return false; | 474 return false; |
440 | 475 |
441 AppendInitSegmentWithEncryptedInfo( | 476 AppendInitSegmentWithEncryptedInfo( |
442 kSourceId, has_audio, has_video, | 477 kSourceId, has_audio, has_video, has_text, |
443 is_audio_encrypted, is_video_encrypted); | 478 is_audio_encrypted, is_video_encrypted); |
444 return true; | 479 return true; |
445 } | 480 } |
446 | 481 |
447 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, | 482 bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id, |
448 const std::string& video_id) { | 483 const std::string& video_id, |
484 bool has_text) { | |
449 EXPECT_CALL(*this, DemuxerOpened()); | 485 EXPECT_CALL(*this, DemuxerOpened()); |
450 demuxer_->Initialize( | 486 demuxer_->Initialize( |
451 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 487 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
452 | 488 |
453 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk) | 489 if (AddId(audio_id, true, false) != ChunkDemuxer::kOk) |
454 return false; | 490 return false; |
455 if (AddId(video_id, false, true) != ChunkDemuxer::kOk) | 491 if (AddId(video_id, false, true) != ChunkDemuxer::kOk) |
456 return false; | 492 return false; |
457 | 493 |
458 AppendInitSegmentWithSourceId(audio_id, true, false); | 494 AppendInitSegmentWithSourceId(audio_id, true, false, has_text); |
459 AppendInitSegmentWithSourceId(video_id, false, true); | 495 AppendInitSegmentWithSourceId(video_id, false, true, has_text); |
460 return true; | 496 return true; |
461 } | 497 } |
462 | 498 |
499 bool InitDemuxerAudioAndVideoSources(const std::string& audio_id, | |
500 const std::string& video_id) { | |
501 return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false); | |
502 } | |
503 | |
463 // Initializes the demuxer with data from 2 files with different | 504 // Initializes the demuxer with data from 2 files with different |
464 // decoder configurations. This is used to test the decoder config change | 505 // decoder configurations. This is used to test the decoder config change |
465 // logic. | 506 // logic. |
466 // | 507 // |
467 // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size() | 508 // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size() |
468 // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size() | 509 // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size() |
469 // The resulting video stream returns data from each file for the following | 510 // The resulting video stream returns data from each file for the following |
470 // time ranges. | 511 // time ranges. |
471 // bear-320x240.webm : [0-501) [801-2737) | 512 // bear-320x240.webm : [0-501) [801-2737) |
472 // bear-640x360.webm : [527-793) | 513 // bear-640x360.webm : [527-793) |
473 // | 514 // |
474 // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size() | 515 // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size() |
475 // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size() | 516 // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size() |
476 // The resulting audio stream returns data from each file for the following | 517 // The resulting audio stream returns data from each file for the following |
477 // time ranges. | 518 // time ranges. |
478 // bear-320x240.webm : [0-524) [779-2737) | 519 // bear-320x240.webm : [0-524) [779-2737) |
479 // bear-640x360.webm : [527-759) | 520 // bear-640x360.webm : [527-759) |
480 bool InitDemuxerWithConfigChangeData() { | 521 bool InitDemuxerWithConfigChangeData() { |
481 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); | 522 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm"); |
482 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); | 523 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm"); |
483 | 524 |
484 EXPECT_CALL(*this, DemuxerOpened()); | 525 EXPECT_CALL(*this, DemuxerOpened()); |
485 demuxer_->Initialize( | 526 demuxer_->Initialize( |
486 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), | 527 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), |
487 PIPELINE_OK)); | 528 PIPELINE_OK), true); |
488 | 529 |
489 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) | 530 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) |
490 return false; | 531 return false; |
491 | 532 |
492 // Append the whole bear1 file. | 533 // Append the whole bear1 file. |
493 AppendData(bear1->data(), bear1->data_size()); | 534 AppendData(bear1->data(), bear1->data_size()); |
494 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); | 535 CheckExpectedRanges(kSourceId, "{ [0,2737) }"); |
495 | 536 |
496 // Append initialization segment for bear2. | 537 // Append initialization segment for bear2. |
497 // Note: Offsets here and below are derived from | 538 // Note: Offsets here and below are derived from |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 const base::TimeDelta& duration) { | 844 const base::TimeDelta& duration) { |
804 return ParseWebMFile(filename, timestamps, duration, true, true); | 845 return ParseWebMFile(filename, timestamps, duration, true, true); |
805 } | 846 } |
806 | 847 |
807 bool ParseWebMFile(const std::string& filename, | 848 bool ParseWebMFile(const std::string& filename, |
808 const BufferTimestamps* timestamps, | 849 const BufferTimestamps* timestamps, |
809 const base::TimeDelta& duration, | 850 const base::TimeDelta& duration, |
810 bool has_audio, bool has_video) { | 851 bool has_audio, bool has_video) { |
811 EXPECT_CALL(*this, DemuxerOpened()); | 852 EXPECT_CALL(*this, DemuxerOpened()); |
812 demuxer_->Initialize( | 853 demuxer_->Initialize( |
813 &host_, CreateInitDoneCB(duration, PIPELINE_OK)); | 854 &host_, CreateInitDoneCB(duration, PIPELINE_OK), true); |
814 | 855 |
815 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) | 856 if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk) |
816 return false; | 857 return false; |
817 | 858 |
818 // Read a WebM file into memory and send the data to the demuxer. | 859 // Read a WebM file into memory and send the data to the demuxer. |
819 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 860 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
820 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); | 861 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); |
821 | 862 |
822 // Verify that the timestamps on the first few packets match what we | 863 // Verify that the timestamps on the first few packets match what we |
823 // expect. | 864 // expect. |
(...skipping 30 matching lines...) Expand all Loading... | |
854 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use | 895 // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use |
855 // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689). | 896 // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689). |
856 MOCK_METHOD3(NeedKeyMock, void(const std::string& type, | 897 MOCK_METHOD3(NeedKeyMock, void(const std::string& type, |
857 const uint8* init_data, int init_data_size)); | 898 const uint8* init_data, int init_data_size)); |
858 void DemuxerNeedKey(const std::string& type, | 899 void DemuxerNeedKey(const std::string& type, |
859 const std::vector<uint8>& init_data) { | 900 const std::vector<uint8>& init_data) { |
860 const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0]; | 901 const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0]; |
861 NeedKeyMock(type, init_data_ptr, init_data.size()); | 902 NeedKeyMock(type, init_data_ptr, init_data.size()); |
862 } | 903 } |
863 | 904 |
864 scoped_ptr<TextTrack> OnTextTrack(TextKind kind, | |
865 const std::string& label, | |
866 const std::string& language) { | |
867 return scoped_ptr<TextTrack>(); | |
868 } | |
869 | |
870 void Seek(base::TimeDelta seek_time) { | 905 void Seek(base::TimeDelta seek_time) { |
871 demuxer_->StartWaitingForSeek(seek_time); | 906 demuxer_->StartWaitingForSeek(seek_time); |
872 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); | 907 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); |
873 message_loop_.RunUntilIdle(); | 908 message_loop_.RunUntilIdle(); |
874 } | 909 } |
875 | 910 |
876 void MarkEndOfStream(PipelineStatus status) { | 911 void MarkEndOfStream(PipelineStatus status) { |
877 demuxer_->MarkEndOfStream(status); | 912 demuxer_->MarkEndOfStream(status); |
878 message_loop_.RunUntilIdle(); | 913 message_loop_.RunUntilIdle(); |
879 } | 914 } |
(...skipping 26 matching lines...) Expand all Loading... | |
906 | 941 |
907 if (is_audio_encrypted || is_video_encrypted) { | 942 if (is_audio_encrypted || is_video_encrypted) { |
908 int need_key_count = (is_audio_encrypted ? 1 : 0) + | 943 int need_key_count = (is_audio_encrypted ? 1 : 0) + |
909 (is_video_encrypted ? 1 : 0); | 944 (is_video_encrypted ? 1 : 0); |
910 EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(), | 945 EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(), |
911 DecryptConfig::kDecryptionKeySize)) | 946 DecryptConfig::kDecryptionKeySize)) |
912 .Times(Exactly(need_key_count)); | 947 .Times(Exactly(need_key_count)); |
913 } | 948 } |
914 | 949 |
915 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | 950 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
916 has_audio, has_video, is_audio_encrypted, is_video_encrypted)); | 951 has_audio, has_video, false, is_audio_encrypted, is_video_encrypted)); |
917 | 952 |
918 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 953 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
919 if (has_audio) { | 954 if (has_audio) { |
955 ASSERT_TRUE(audio_stream); | |
956 | |
957 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | |
958 EXPECT_EQ(kCodecVorbis, config.codec()); | |
959 EXPECT_EQ(32, config.bits_per_channel()); | |
960 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); | |
961 EXPECT_EQ(44100, config.samples_per_second()); | |
962 EXPECT_TRUE(config.extra_data()); | |
963 EXPECT_GT(config.extra_data_size(), 0u); | |
964 EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format()); | |
965 EXPECT_EQ(is_audio_encrypted, | |
966 audio_stream->audio_decoder_config().is_encrypted()); | |
967 } else { | |
968 EXPECT_FALSE(audio_stream); | |
969 } | |
970 | |
971 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | |
972 if (has_video) { | |
973 EXPECT_TRUE(video_stream); | |
974 EXPECT_EQ(is_video_encrypted, | |
975 video_stream->video_decoder_config().is_encrypted()); | |
976 } else { | |
977 EXPECT_FALSE(video_stream); | |
978 } | |
979 | |
980 ShutdownDemuxer(); | |
981 demuxer_.reset(); | |
982 } | |
983 } | |
984 | |
985 TEST_F(ChunkDemuxerTest, InitText) { | |
986 // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams. | |
987 // No encryption cases handled here. | |
988 bool has_video = true; | |
989 bool has_text = true; | |
990 bool is_audio_encrypted = false; | |
991 bool is_video_encrypted = false; | |
992 for (int i = 0; i < 2; i++) { | |
993 bool has_audio = (i & 0x1) != 0; | |
994 | |
995 CreateNewDemuxer(); | |
996 | |
997 DemuxerStream* text_stream = NULL; | |
998 TextTrackConfig text_config; | |
999 EXPECT_CALL(host_, AddTextStream(_,_)) | |
1000 .WillOnce(DoAll(SaveArg<0>(&text_stream), | |
1001 SaveArg<1>(&text_config))); | |
1002 | |
1003 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | |
1004 has_audio, has_video, true, is_audio_encrypted, is_video_encrypted)); | |
1005 ASSERT_TRUE(text_stream); | |
1006 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | |
1007 EXPECT_EQ(kTextSubtitles, text_config.kind()); | |
1008 | |
1009 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
1010 if (has_audio) { | |
920 ASSERT_TRUE(audio_stream); | 1011 ASSERT_TRUE(audio_stream); |
921 | 1012 |
922 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 1013 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
923 EXPECT_EQ(kCodecVorbis, config.codec()); | 1014 EXPECT_EQ(kCodecVorbis, config.codec()); |
924 EXPECT_EQ(32, config.bits_per_channel()); | 1015 EXPECT_EQ(32, config.bits_per_channel()); |
925 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); | 1016 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); |
926 EXPECT_EQ(44100, config.samples_per_second()); | 1017 EXPECT_EQ(44100, config.samples_per_second()); |
927 EXPECT_TRUE(config.extra_data()); | 1018 EXPECT_TRUE(config.extra_data()); |
928 EXPECT_GT(config.extra_data_size(), 0u); | 1019 EXPECT_GT(config.extra_data_size(), 0u); |
929 EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format()); | 1020 EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format()); |
(...skipping 16 matching lines...) Expand all Loading... | |
946 demuxer_.reset(); | 1037 demuxer_.reset(); |
947 } | 1038 } |
948 } | 1039 } |
949 | 1040 |
950 // Make sure that the demuxer reports an error if Shutdown() | 1041 // Make sure that the demuxer reports an error if Shutdown() |
951 // is called before all the initialization segments are appended. | 1042 // is called before all the initialization segments are appended. |
952 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) { | 1043 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) { |
953 EXPECT_CALL(*this, DemuxerOpened()); | 1044 EXPECT_CALL(*this, DemuxerOpened()); |
954 demuxer_->Initialize( | 1045 demuxer_->Initialize( |
955 &host_, CreateInitDoneCB( | 1046 &host_, CreateInitDoneCB( |
956 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1047 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
957 | 1048 |
958 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1049 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
959 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1050 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
960 | 1051 |
961 AppendInitSegmentWithSourceId("audio", true, false); | 1052 AppendInitSegmentWithSourceId("audio", true, false, false); |
1053 } | |
1054 | |
1055 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppendedText) { | |
1056 EXPECT_CALL(*this, DemuxerOpened()); | |
1057 demuxer_->Initialize( | |
1058 &host_, CreateInitDoneCB( | |
1059 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | |
1060 | |
1061 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | |
1062 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | |
1063 | |
1064 EXPECT_CALL(host_, AddTextStream(_,_)) | |
1065 .Times(Exactly(1)); | |
1066 | |
1067 AppendInitSegmentWithSourceId("video", false, true, true); | |
962 } | 1068 } |
963 | 1069 |
964 // Test that Seek() completes successfully when the first cluster | 1070 // Test that Seek() completes successfully when the first cluster |
965 // arrives. | 1071 // arrives. |
966 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { | 1072 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { |
967 ASSERT_TRUE(InitDemuxer(true, true)); | 1073 ASSERT_TRUE(InitDemuxer(true, true)); |
968 AppendCluster(kDefaultFirstCluster()); | 1074 AppendCluster(kDefaultFirstCluster()); |
969 | 1075 |
970 InSequence s; | 1076 InSequence s; |
971 | 1077 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1026 // Append the new cluster and verify that only the blocks | 1132 // Append the new cluster and verify that only the blocks |
1027 // in the new cluster are returned. | 1133 // in the new cluster are returned. |
1028 AppendCluster(GenerateCluster(5000, 6)); | 1134 AppendCluster(GenerateCluster(5000, 6)); |
1029 GenerateExpectedReads(5000, 6); | 1135 GenerateExpectedReads(5000, 6); |
1030 } | 1136 } |
1031 | 1137 |
1032 // Test the case where AppendData() is called before Init(). | 1138 // Test the case where AppendData() is called before Init(). |
1033 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { | 1139 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { |
1034 scoped_ptr<uint8[]> info_tracks; | 1140 scoped_ptr<uint8[]> info_tracks; |
1035 int info_tracks_size = 0; | 1141 int info_tracks_size = 0; |
1036 CreateInitSegment(true, true, false, false, &info_tracks, &info_tracks_size); | 1142 CreateInitSegment(true, true, false, |
1143 false, false, &info_tracks, &info_tracks_size); | |
1037 | 1144 |
1038 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); | 1145 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); |
1039 } | 1146 } |
1040 | 1147 |
1041 // Make sure Read() callbacks are dispatched with the proper data. | 1148 // Make sure Read() callbacks are dispatched with the proper data. |
1042 TEST_F(ChunkDemuxerTest, Read) { | 1149 TEST_F(ChunkDemuxerTest, Read) { |
1043 ASSERT_TRUE(InitDemuxer(true, true)); | 1150 ASSERT_TRUE(InitDemuxer(true, true)); |
1044 | 1151 |
1045 AppendCluster(kDefaultFirstCluster()); | 1152 AppendCluster(kDefaultFirstCluster()); |
1046 | 1153 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 | 1239 |
1133 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1240 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
1134 AppendCluster(cb.Finish()); | 1241 AppendCluster(cb.Finish()); |
1135 } | 1242 } |
1136 | 1243 |
1137 // Test the case where a cluster is passed to AppendCluster() before | 1244 // Test the case where a cluster is passed to AppendCluster() before |
1138 // INFO & TRACKS data. | 1245 // INFO & TRACKS data. |
1139 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) { | 1246 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) { |
1140 EXPECT_CALL(*this, DemuxerOpened()); | 1247 EXPECT_CALL(*this, DemuxerOpened()); |
1141 demuxer_->Initialize( | 1248 demuxer_->Initialize( |
1142 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1249 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1143 | 1250 |
1144 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1251 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1145 | 1252 |
1146 AppendCluster(GenerateCluster(0, 1)); | 1253 AppendCluster(GenerateCluster(0, 1)); |
1147 } | 1254 } |
1148 | 1255 |
1149 // Test cases where we get an MarkEndOfStream() call during initialization. | 1256 // Test cases where we get an MarkEndOfStream() call during initialization. |
1150 TEST_F(ChunkDemuxerTest, EOSDuringInit) { | 1257 TEST_F(ChunkDemuxerTest, EOSDuringInit) { |
1151 EXPECT_CALL(*this, DemuxerOpened()); | 1258 EXPECT_CALL(*this, DemuxerOpened()); |
1152 demuxer_->Initialize( | 1259 demuxer_->Initialize( |
1153 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1260 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1154 MarkEndOfStream(PIPELINE_OK); | 1261 MarkEndOfStream(PIPELINE_OK); |
1155 } | 1262 } |
1156 | 1263 |
1157 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) { | 1264 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) { |
1158 EXPECT_CALL(*this, DemuxerOpened()); | 1265 EXPECT_CALL(*this, DemuxerOpened()); |
1159 demuxer_->Initialize( | 1266 demuxer_->Initialize( |
1160 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1267 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1161 | 1268 |
1162 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1269 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1163 | 1270 |
1164 CheckExpectedRanges("{ }"); | 1271 CheckExpectedRanges("{ }"); |
1165 MarkEndOfStream(PIPELINE_OK); | 1272 MarkEndOfStream(PIPELINE_OK); |
1166 ShutdownDemuxer(); | 1273 ShutdownDemuxer(); |
1167 CheckExpectedRanges("{ }"); | 1274 CheckExpectedRanges("{ }"); |
1168 demuxer_->RemoveId(kSourceId); | 1275 demuxer_->RemoveId(kSourceId); |
1169 demuxer_.reset(); | 1276 demuxer_.reset(); |
1170 } | 1277 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1349 | 1456 |
1350 // Make sure video can reach end of stream. | 1457 // Make sure video can reach end of stream. |
1351 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 1458 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
1352 ASSERT_EQ(status, DemuxerStream::kOk); | 1459 ASSERT_EQ(status, DemuxerStream::kOk); |
1353 } | 1460 } |
1354 | 1461 |
1355 // Make sure AppendData() will accept elements that span multiple calls. | 1462 // Make sure AppendData() will accept elements that span multiple calls. |
1356 TEST_F(ChunkDemuxerTest, AppendingInPieces) { | 1463 TEST_F(ChunkDemuxerTest, AppendingInPieces) { |
1357 EXPECT_CALL(*this, DemuxerOpened()); | 1464 EXPECT_CALL(*this, DemuxerOpened()); |
1358 demuxer_->Initialize( | 1465 demuxer_->Initialize( |
1359 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1466 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1360 | 1467 |
1361 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1468 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1362 | 1469 |
1363 scoped_ptr<uint8[]> info_tracks; | 1470 scoped_ptr<uint8[]> info_tracks; |
1364 int info_tracks_size = 0; | 1471 int info_tracks_size = 0; |
1365 CreateInitSegment(true, true, false, false, &info_tracks, &info_tracks_size); | 1472 CreateInitSegment(true, true, false, |
1473 false, false, &info_tracks, &info_tracks_size); | |
1366 | 1474 |
1367 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 1475 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
1368 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); | 1476 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); |
1369 | 1477 |
1370 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); | 1478 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); |
1371 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); | 1479 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); |
1372 uint8* dst = buffer.get(); | 1480 uint8* dst = buffer.get(); |
1373 memcpy(dst, info_tracks.get(), info_tracks_size); | 1481 memcpy(dst, info_tracks.get(), info_tracks_size); |
1374 dst += info_tracks_size; | 1482 dst += info_tracks_size; |
1375 | 1483 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1517 message_loop_.RunUntilIdle(); | 1625 message_loop_.RunUntilIdle(); |
1518 | 1626 |
1519 EXPECT_TRUE(audio_read_done); | 1627 EXPECT_TRUE(audio_read_done); |
1520 EXPECT_TRUE(video_read_done); | 1628 EXPECT_TRUE(video_read_done); |
1521 } | 1629 } |
1522 | 1630 |
1523 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { | 1631 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { |
1524 EXPECT_CALL(*this, DemuxerOpened()); | 1632 EXPECT_CALL(*this, DemuxerOpened()); |
1525 demuxer_->Initialize( | 1633 demuxer_->Initialize( |
1526 &host_, CreateInitDoneCB( | 1634 &host_, CreateInitDoneCB( |
1527 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1635 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1528 | 1636 |
1529 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1637 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1530 | 1638 |
1531 uint8 tmp = 0; | 1639 uint8 tmp = 0; |
1532 demuxer_->AppendData(kSourceId, &tmp, 1); | 1640 demuxer_->AppendData(kSourceId, &tmp, 1); |
1533 } | 1641 } |
1534 | 1642 |
1535 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { | 1643 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { |
1536 EXPECT_CALL(*this, DemuxerOpened()); | 1644 EXPECT_CALL(*this, DemuxerOpened()); |
1537 demuxer_->Initialize( | 1645 demuxer_->Initialize( |
1538 &host_, CreateInitDoneCB(kNoTimestamp(), | 1646 &host_, CreateInitDoneCB(kNoTimestamp(), |
1539 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1647 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1540 | 1648 |
1541 std::vector<std::string> codecs(1); | 1649 std::vector<std::string> codecs(1); |
1542 codecs[0] = "vorbis"; | 1650 codecs[0] = "vorbis"; |
1543 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 1651 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
1544 ChunkDemuxer::kOk); | 1652 ChunkDemuxer::kOk); |
1545 | 1653 |
1546 AppendInitSegment(true, true); | 1654 AppendInitSegment(true, true); |
1547 } | 1655 } |
1548 | 1656 |
1549 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { | 1657 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { |
1550 EXPECT_CALL(*this, DemuxerOpened()); | 1658 EXPECT_CALL(*this, DemuxerOpened()); |
1551 demuxer_->Initialize( | 1659 demuxer_->Initialize( |
1552 &host_, CreateInitDoneCB(kNoTimestamp(), | 1660 &host_, CreateInitDoneCB(kNoTimestamp(), |
1553 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1661 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1554 | 1662 |
1555 std::vector<std::string> codecs(1); | 1663 std::vector<std::string> codecs(1); |
1556 codecs[0] = "vp8"; | 1664 codecs[0] = "vp8"; |
1557 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1665 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
1558 ChunkDemuxer::kOk); | 1666 ChunkDemuxer::kOk); |
1559 | 1667 |
1560 AppendInitSegment(true, true); | 1668 AppendInitSegment(true, true); |
1561 } | 1669 } |
1562 | 1670 |
1563 TEST_F(ChunkDemuxerTest, MultipleHeaders) { | 1671 TEST_F(ChunkDemuxerTest, MultipleHeaders) { |
(...skipping 16 matching lines...) Expand all Loading... | |
1580 | 1688 |
1581 // Append audio and video data into separate source ids. | 1689 // Append audio and video data into separate source ids. |
1582 AppendCluster(audio_id, | 1690 AppendCluster(audio_id, |
1583 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 1691 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1584 GenerateAudioStreamExpectedReads(0, 4); | 1692 GenerateAudioStreamExpectedReads(0, 4); |
1585 AppendCluster(video_id, | 1693 AppendCluster(video_id, |
1586 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 1694 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1587 GenerateVideoStreamExpectedReads(0, 4); | 1695 GenerateVideoStreamExpectedReads(0, 4); |
1588 } | 1696 } |
1589 | 1697 |
1698 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) { | |
acolwell GONE FROM CHROMIUM
2013/11/20 01:15:24
File a bug to track adding more ChunkDemuxer tests
Matthew Heaney (Chromium)
2013/11/20 19:23:16
Added CR:
https://code.google.com/p/chromium/issue
| |
1699 std::string audio_id = "audio1"; | |
1700 std::string video_id = "video1"; | |
1701 | |
1702 EXPECT_CALL(host_, AddTextStream(_,_)) | |
1703 .Times(Exactly(2)); | |
1704 ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, true)); | |
1705 | |
1706 // Append audio and video data into separate source ids. | |
1707 AppendCluster(audio_id, | |
1708 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | |
1709 GenerateAudioStreamExpectedReads(0, 4); | |
1710 AppendCluster(video_id, | |
1711 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | |
1712 GenerateVideoStreamExpectedReads(0, 4); | |
1713 } | |
1714 | |
1590 TEST_F(ChunkDemuxerTest, AddIdFailures) { | 1715 TEST_F(ChunkDemuxerTest, AddIdFailures) { |
1591 EXPECT_CALL(*this, DemuxerOpened()); | 1716 EXPECT_CALL(*this, DemuxerOpened()); |
1592 demuxer_->Initialize( | 1717 demuxer_->Initialize( |
1593 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1718 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1594 | 1719 |
1595 std::string audio_id = "audio1"; | 1720 std::string audio_id = "audio1"; |
1596 std::string video_id = "video1"; | 1721 std::string video_id = "video1"; |
1597 | 1722 |
1598 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); | 1723 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); |
1599 | 1724 |
1600 // Adding an id with audio/video should fail because we already added audio. | 1725 // Adding an id with audio/video should fail because we already added audio. |
1601 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 1726 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); |
1602 | 1727 |
1603 AppendInitSegmentWithSourceId(audio_id, true, false); | 1728 AppendInitSegmentWithSourceId(audio_id, true, false, false); |
1604 | 1729 |
1605 // Adding an id after append should fail. | 1730 // Adding an id after append should fail. |
1606 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); | 1731 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); |
1607 } | 1732 } |
1608 | 1733 |
1609 // Test that Read() calls after a RemoveId() return "end of stream" buffers. | 1734 // Test that Read() calls after a RemoveId() return "end of stream" buffers. |
1610 TEST_F(ChunkDemuxerTest, RemoveId) { | 1735 TEST_F(ChunkDemuxerTest, RemoveId) { |
1611 std::string audio_id = "audio1"; | 1736 std::string audio_id = "audio1"; |
1612 std::string video_id = "video1"; | 1737 std::string video_id = "video1"; |
1613 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1738 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1822 | 1947 |
1823 EXPECT_TRUE(seek_cb_was_called); | 1948 EXPECT_TRUE(seek_cb_was_called); |
1824 | 1949 |
1825 ShutdownDemuxer(); | 1950 ShutdownDemuxer(); |
1826 } | 1951 } |
1827 | 1952 |
1828 // Test ranges in an audio-only stream. | 1953 // Test ranges in an audio-only stream. |
1829 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 1954 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
1830 EXPECT_CALL(*this, DemuxerOpened()); | 1955 EXPECT_CALL(*this, DemuxerOpened()); |
1831 demuxer_->Initialize( | 1956 demuxer_->Initialize( |
1832 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1957 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1833 | 1958 |
1834 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 1959 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); |
1835 AppendInitSegment(true, false); | 1960 AppendInitSegment(true, false); |
1836 | 1961 |
1837 // Test a simple cluster. | 1962 // Test a simple cluster. |
1838 AppendCluster( | 1963 AppendCluster( |
1839 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 1964 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1840 | 1965 |
1841 CheckExpectedRanges("{ [0,92) }"); | 1966 CheckExpectedRanges("{ [0,92) }"); |
1842 | 1967 |
1843 // Append a disjoint cluster to check for two separate ranges. | 1968 // Append a disjoint cluster to check for two separate ranges. |
1844 AppendCluster(GenerateSingleStreamCluster( | 1969 AppendCluster(GenerateSingleStreamCluster( |
1845 150, 219, kAudioTrackNum, kAudioBlockDuration)); | 1970 150, 219, kAudioTrackNum, kAudioBlockDuration)); |
1846 | 1971 |
1847 CheckExpectedRanges("{ [0,92) [150,219) }"); | 1972 CheckExpectedRanges("{ [0,92) [150,219) }"); |
1848 } | 1973 } |
1849 | 1974 |
1850 // Test ranges in a video-only stream. | 1975 // Test ranges in a video-only stream. |
1851 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 1976 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
1852 EXPECT_CALL(*this, DemuxerOpened()); | 1977 EXPECT_CALL(*this, DemuxerOpened()); |
1853 demuxer_->Initialize( | 1978 demuxer_->Initialize( |
1854 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1979 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1855 | 1980 |
1856 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 1981 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); |
1857 AppendInitSegment(false, true); | 1982 AppendInitSegment(false, true); |
1858 | 1983 |
1859 // Test a simple cluster. | 1984 // Test a simple cluster. |
1860 AppendCluster( | 1985 AppendCluster( |
1861 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 1986 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1862 | 1987 |
1863 CheckExpectedRanges("{ [0,132) }"); | 1988 CheckExpectedRanges("{ [0,132) }"); |
1864 | 1989 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2086 EXPECT_EQ(DemuxerStream::kOk, status); | 2211 EXPECT_EQ(DemuxerStream::kOk, status); |
2087 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); | 2212 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); |
2088 | 2213 |
2089 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 2214 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
2090 EXPECT_EQ(DemuxerStream::kOk, status); | 2215 EXPECT_EQ(DemuxerStream::kOk, status); |
2091 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); | 2216 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); |
2092 } | 2217 } |
2093 | 2218 |
2094 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { | 2219 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { |
2095 EXPECT_CALL(*this, DemuxerOpened()); | 2220 EXPECT_CALL(*this, DemuxerOpened()); |
2096 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); | 2221 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true); |
2097 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 2222 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
2098 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 2223 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
2099 | 2224 |
2100 CheckExpectedRanges("audio", "{ }"); | 2225 CheckExpectedRanges("audio", "{ }"); |
2101 CheckExpectedRanges("video", "{ }"); | 2226 CheckExpectedRanges("video", "{ }"); |
2102 } | 2227 } |
2103 | 2228 |
2104 // Test that Seek() completes successfully when the first cluster | 2229 // Test that Seek() completes successfully when the first cluster |
2105 // arrives. | 2230 // arrives. |
2106 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { | 2231 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2410 AppendCluster(kDefaultSecondCluster()); | 2535 AppendCluster(kDefaultSecondCluster()); |
2411 MarkEndOfStream(PIPELINE_OK); | 2536 MarkEndOfStream(PIPELINE_OK); |
2412 } | 2537 } |
2413 | 2538 |
2414 // Test receiving a Shutdown() call before we get an Initialize() | 2539 // Test receiving a Shutdown() call before we get an Initialize() |
2415 // call. This can happen if video element gets destroyed before | 2540 // call. This can happen if video element gets destroyed before |
2416 // the pipeline has a chance to initialize the demuxer. | 2541 // the pipeline has a chance to initialize the demuxer. |
2417 TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) { | 2542 TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) { |
2418 demuxer_->Shutdown(); | 2543 demuxer_->Shutdown(); |
2419 demuxer_->Initialize( | 2544 demuxer_->Initialize( |
2420 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 2545 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
2421 message_loop_.RunUntilIdle(); | 2546 message_loop_.RunUntilIdle(); |
2422 } | 2547 } |
2423 | 2548 |
2424 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { | 2549 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { |
2425 ASSERT_TRUE(InitDemuxer(true, true)); | 2550 ASSERT_TRUE(InitDemuxer(true, true)); |
2426 AppendCluster(kDefaultFirstCluster()); | 2551 AppendCluster(kDefaultFirstCluster()); |
2427 | 2552 |
2428 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 2553 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
2429 ASSERT_TRUE(stream); | 2554 ASSERT_TRUE(stream); |
2430 | 2555 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2559 // NOTE: The current GC algorithm tries to preserve the GOP at the | 2684 // NOTE: The current GC algorithm tries to preserve the GOP at the |
2560 // current position as well as the last appended GOP. This is | 2685 // current position as well as the last appended GOP. This is |
2561 // why there are 2 ranges in the expectations. | 2686 // why there are 2 ranges in the expectations. |
2562 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); | 2687 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); |
2563 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); | 2688 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); |
2564 } | 2689 } |
2565 | 2690 |
2566 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { | 2691 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { |
2567 EXPECT_CALL(*this, DemuxerOpened()); | 2692 EXPECT_CALL(*this, DemuxerOpened()); |
2568 demuxer_->Initialize( | 2693 demuxer_->Initialize( |
2569 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK)); | 2694 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true); |
2570 | 2695 |
2571 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); | 2696 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); |
2572 | 2697 |
2573 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), | 2698 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), |
2574 base::TimeDelta::FromMilliseconds(1)); | 2699 base::TimeDelta::FromMilliseconds(1)); |
2575 } | 2700 } |
2576 | 2701 |
2577 TEST_F(ChunkDemuxerTest, AppendWindow) { | 2702 TEST_F(ChunkDemuxerTest, AppendWindow) { |
2578 ASSERT_TRUE(InitDemuxer(false, true)); | 2703 ASSERT_TRUE(InitDemuxer(false, true)); |
2579 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 2704 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
(...skipping 27 matching lines...) Expand all Loading... | |
2607 | 2732 |
2608 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { | 2733 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { |
2609 ASSERT_TRUE(InitDemuxer(true, true)); | 2734 ASSERT_TRUE(InitDemuxer(true, true)); |
2610 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 2735 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
2611 AppendGarbage(); | 2736 AppendGarbage(); |
2612 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); | 2737 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); |
2613 demuxer_->StartWaitingForSeek(seek_time); | 2738 demuxer_->StartWaitingForSeek(seek_time); |
2614 } | 2739 } |
2615 | 2740 |
2616 } // namespace media | 2741 } // namespace media |
OLD | NEW |