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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 152 |
153 ChunkDemuxerTest() { | 153 ChunkDemuxerTest() { |
154 CreateNewDemuxer(); | 154 CreateNewDemuxer(); |
155 } | 155 } |
156 | 156 |
157 void CreateNewDemuxer() { | 157 void CreateNewDemuxer() { |
158 base::Closure open_cb = | 158 base::Closure open_cb = |
159 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); | 159 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
160 Demuxer::NeedKeyCB need_key_cb = | 160 Demuxer::NeedKeyCB need_key_cb = |
161 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); | 161 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); |
162 AddTextTrackCB add_text_track_cb = | 162 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 } | 163 } |
167 | 164 |
168 virtual ~ChunkDemuxerTest() { | 165 virtual ~ChunkDemuxerTest() { |
169 ShutdownDemuxer(); | 166 ShutdownDemuxer(); |
170 } | 167 } |
171 | 168 |
172 void CreateInitSegment(bool has_audio, bool has_video, | 169 void CreateInitSegment(bool has_audio, bool has_video, bool has_text, |
173 bool is_audio_encrypted, bool is_video_encrypted, | 170 bool is_audio_encrypted, bool is_video_encrypted, |
174 scoped_ptr<uint8[]>* buffer, | 171 scoped_ptr<uint8[]>* buffer, |
175 int* size) { | 172 int* size) { |
176 scoped_refptr<DecoderBuffer> ebml_header; | 173 scoped_refptr<DecoderBuffer> ebml_header; |
177 scoped_refptr<DecoderBuffer> info; | 174 scoped_refptr<DecoderBuffer> info; |
178 scoped_refptr<DecoderBuffer> audio_track_entry; | 175 scoped_refptr<DecoderBuffer> audio_track_entry; |
179 scoped_refptr<DecoderBuffer> video_track_entry; | 176 scoped_refptr<DecoderBuffer> video_track_entry; |
180 scoped_refptr<DecoderBuffer> audio_content_encodings; | 177 scoped_refptr<DecoderBuffer> audio_content_encodings; |
181 scoped_refptr<DecoderBuffer> video_content_encodings; | 178 scoped_refptr<DecoderBuffer> video_content_encodings; |
| 179 scoped_refptr<DecoderBuffer> text_track_entry; |
182 | 180 |
183 ebml_header = ReadTestDataFile("webm_ebml_element"); | 181 ebml_header = ReadTestDataFile("webm_ebml_element"); |
184 | 182 |
185 info = ReadTestDataFile("webm_info_element"); | 183 info = ReadTestDataFile("webm_info_element"); |
186 | 184 |
187 int tracks_element_size = 0; | 185 int tracks_element_size = 0; |
188 | 186 |
189 if (has_audio) { | 187 if (has_audio) { |
190 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); | 188 audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry"); |
191 tracks_element_size += audio_track_entry->data_size(); | 189 tracks_element_size += audio_track_entry->data_size(); |
192 if (is_audio_encrypted) { | 190 if (is_audio_encrypted) { |
193 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); | 191 audio_content_encodings = ReadTestDataFile("webm_content_encodings"); |
194 tracks_element_size += audio_content_encodings->data_size(); | 192 tracks_element_size += audio_content_encodings->data_size(); |
195 } | 193 } |
196 } | 194 } |
197 | 195 |
198 if (has_video) { | 196 if (has_video) { |
199 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); | 197 video_track_entry = ReadTestDataFile("webm_vp8_track_entry"); |
200 tracks_element_size += video_track_entry->data_size(); | 198 tracks_element_size += video_track_entry->data_size(); |
201 if (is_video_encrypted) { | 199 if (is_video_encrypted) { |
202 video_content_encodings = ReadTestDataFile("webm_content_encodings"); | 200 video_content_encodings = ReadTestDataFile("webm_content_encodings"); |
203 tracks_element_size += video_content_encodings->data_size(); | 201 tracks_element_size += video_content_encodings->data_size(); |
204 } | 202 } |
205 } | 203 } |
206 | 204 |
| 205 if (has_text) { |
| 206 // TODO(matthewjheaney): create an abstraction to do |
| 207 // this (http://crbug/321454). |
| 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 is_audio_encrypted = false; |
| 990 bool is_video_encrypted = false; |
| 991 for (int i = 0; i < 2; i++) { |
| 992 bool has_audio = (i & 0x1) != 0; |
| 993 |
| 994 CreateNewDemuxer(); |
| 995 |
| 996 DemuxerStream* text_stream = NULL; |
| 997 TextTrackConfig text_config; |
| 998 EXPECT_CALL(host_, AddTextStream(_,_)) |
| 999 .WillOnce(DoAll(SaveArg<0>(&text_stream), |
| 1000 SaveArg<1>(&text_config))); |
| 1001 |
| 1002 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
| 1003 has_audio, has_video, true, is_audio_encrypted, is_video_encrypted)); |
| 1004 ASSERT_TRUE(text_stream); |
| 1005 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 1006 EXPECT_EQ(kTextSubtitles, text_config.kind()); |
| 1007 |
| 1008 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 1009 if (has_audio) { |
920 ASSERT_TRUE(audio_stream); | 1010 ASSERT_TRUE(audio_stream); |
921 | 1011 |
922 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); | 1012 const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
923 EXPECT_EQ(kCodecVorbis, config.codec()); | 1013 EXPECT_EQ(kCodecVorbis, config.codec()); |
924 EXPECT_EQ(32, config.bits_per_channel()); | 1014 EXPECT_EQ(32, config.bits_per_channel()); |
925 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); | 1015 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout()); |
926 EXPECT_EQ(44100, config.samples_per_second()); | 1016 EXPECT_EQ(44100, config.samples_per_second()); |
927 EXPECT_TRUE(config.extra_data()); | 1017 EXPECT_TRUE(config.extra_data()); |
928 EXPECT_GT(config.extra_data_size(), 0u); | 1018 EXPECT_GT(config.extra_data_size(), 0u); |
929 EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format()); | 1019 EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format()); |
(...skipping 16 matching lines...) Expand all Loading... |
946 demuxer_.reset(); | 1036 demuxer_.reset(); |
947 } | 1037 } |
948 } | 1038 } |
949 | 1039 |
950 // Make sure that the demuxer reports an error if Shutdown() | 1040 // Make sure that the demuxer reports an error if Shutdown() |
951 // is called before all the initialization segments are appended. | 1041 // is called before all the initialization segments are appended. |
952 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) { | 1042 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) { |
953 EXPECT_CALL(*this, DemuxerOpened()); | 1043 EXPECT_CALL(*this, DemuxerOpened()); |
954 demuxer_->Initialize( | 1044 demuxer_->Initialize( |
955 &host_, CreateInitDoneCB( | 1045 &host_, CreateInitDoneCB( |
956 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1046 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
957 | 1047 |
958 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 1048 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
959 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 1049 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
960 | 1050 |
961 AppendInitSegmentWithSourceId("audio", true, false); | 1051 AppendInitSegmentWithSourceId("audio", true, false, false); |
| 1052 } |
| 1053 |
| 1054 TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppendedText) { |
| 1055 EXPECT_CALL(*this, DemuxerOpened()); |
| 1056 demuxer_->Initialize( |
| 1057 &host_, CreateInitDoneCB( |
| 1058 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
| 1059 |
| 1060 EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
| 1061 EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
| 1062 |
| 1063 EXPECT_CALL(host_, AddTextStream(_,_)) |
| 1064 .Times(Exactly(1)); |
| 1065 |
| 1066 AppendInitSegmentWithSourceId("video", false, true, true); |
962 } | 1067 } |
963 | 1068 |
964 // Test that Seek() completes successfully when the first cluster | 1069 // Test that Seek() completes successfully when the first cluster |
965 // arrives. | 1070 // arrives. |
966 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { | 1071 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) { |
967 ASSERT_TRUE(InitDemuxer(true, true)); | 1072 ASSERT_TRUE(InitDemuxer(true, true)); |
968 AppendCluster(kDefaultFirstCluster()); | 1073 AppendCluster(kDefaultFirstCluster()); |
969 | 1074 |
970 InSequence s; | 1075 InSequence s; |
971 | 1076 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 // Append the new cluster and verify that only the blocks | 1131 // Append the new cluster and verify that only the blocks |
1027 // in the new cluster are returned. | 1132 // in the new cluster are returned. |
1028 AppendCluster(GenerateCluster(5000, 6)); | 1133 AppendCluster(GenerateCluster(5000, 6)); |
1029 GenerateExpectedReads(5000, 6); | 1134 GenerateExpectedReads(5000, 6); |
1030 } | 1135 } |
1031 | 1136 |
1032 // Test the case where AppendData() is called before Init(). | 1137 // Test the case where AppendData() is called before Init(). |
1033 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { | 1138 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { |
1034 scoped_ptr<uint8[]> info_tracks; | 1139 scoped_ptr<uint8[]> info_tracks; |
1035 int info_tracks_size = 0; | 1140 int info_tracks_size = 0; |
1036 CreateInitSegment(true, true, false, false, &info_tracks, &info_tracks_size); | 1141 CreateInitSegment(true, true, false, |
| 1142 false, false, &info_tracks, &info_tracks_size); |
1037 | 1143 |
1038 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); | 1144 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size); |
1039 } | 1145 } |
1040 | 1146 |
1041 // Make sure Read() callbacks are dispatched with the proper data. | 1147 // Make sure Read() callbacks are dispatched with the proper data. |
1042 TEST_F(ChunkDemuxerTest, Read) { | 1148 TEST_F(ChunkDemuxerTest, Read) { |
1043 ASSERT_TRUE(InitDemuxer(true, true)); | 1149 ASSERT_TRUE(InitDemuxer(true, true)); |
1044 | 1150 |
1045 AppendCluster(kDefaultFirstCluster()); | 1151 AppendCluster(kDefaultFirstCluster()); |
1046 | 1152 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 | 1238 |
1133 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1239 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
1134 AppendCluster(cb.Finish()); | 1240 AppendCluster(cb.Finish()); |
1135 } | 1241 } |
1136 | 1242 |
1137 // Test the case where a cluster is passed to AppendCluster() before | 1243 // Test the case where a cluster is passed to AppendCluster() before |
1138 // INFO & TRACKS data. | 1244 // INFO & TRACKS data. |
1139 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) { | 1245 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) { |
1140 EXPECT_CALL(*this, DemuxerOpened()); | 1246 EXPECT_CALL(*this, DemuxerOpened()); |
1141 demuxer_->Initialize( | 1247 demuxer_->Initialize( |
1142 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1248 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1143 | 1249 |
1144 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1250 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1145 | 1251 |
1146 AppendCluster(GenerateCluster(0, 1)); | 1252 AppendCluster(GenerateCluster(0, 1)); |
1147 } | 1253 } |
1148 | 1254 |
1149 // Test cases where we get an MarkEndOfStream() call during initialization. | 1255 // Test cases where we get an MarkEndOfStream() call during initialization. |
1150 TEST_F(ChunkDemuxerTest, EOSDuringInit) { | 1256 TEST_F(ChunkDemuxerTest, EOSDuringInit) { |
1151 EXPECT_CALL(*this, DemuxerOpened()); | 1257 EXPECT_CALL(*this, DemuxerOpened()); |
1152 demuxer_->Initialize( | 1258 demuxer_->Initialize( |
1153 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1259 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1154 MarkEndOfStream(PIPELINE_OK); | 1260 MarkEndOfStream(PIPELINE_OK); |
1155 } | 1261 } |
1156 | 1262 |
1157 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) { | 1263 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) { |
1158 EXPECT_CALL(*this, DemuxerOpened()); | 1264 EXPECT_CALL(*this, DemuxerOpened()); |
1159 demuxer_->Initialize( | 1265 demuxer_->Initialize( |
1160 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 1266 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1161 | 1267 |
1162 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1268 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1163 | 1269 |
1164 CheckExpectedRanges("{ }"); | 1270 CheckExpectedRanges("{ }"); |
1165 MarkEndOfStream(PIPELINE_OK); | 1271 MarkEndOfStream(PIPELINE_OK); |
1166 ShutdownDemuxer(); | 1272 ShutdownDemuxer(); |
1167 CheckExpectedRanges("{ }"); | 1273 CheckExpectedRanges("{ }"); |
1168 demuxer_->RemoveId(kSourceId); | 1274 demuxer_->RemoveId(kSourceId); |
1169 demuxer_.reset(); | 1275 demuxer_.reset(); |
1170 } | 1276 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 | 1455 |
1350 // Make sure video can reach end of stream. | 1456 // Make sure video can reach end of stream. |
1351 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 1457 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
1352 ASSERT_EQ(status, DemuxerStream::kOk); | 1458 ASSERT_EQ(status, DemuxerStream::kOk); |
1353 } | 1459 } |
1354 | 1460 |
1355 // Make sure AppendData() will accept elements that span multiple calls. | 1461 // Make sure AppendData() will accept elements that span multiple calls. |
1356 TEST_F(ChunkDemuxerTest, AppendingInPieces) { | 1462 TEST_F(ChunkDemuxerTest, AppendingInPieces) { |
1357 EXPECT_CALL(*this, DemuxerOpened()); | 1463 EXPECT_CALL(*this, DemuxerOpened()); |
1358 demuxer_->Initialize( | 1464 demuxer_->Initialize( |
1359 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1465 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1360 | 1466 |
1361 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1467 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1362 | 1468 |
1363 scoped_ptr<uint8[]> info_tracks; | 1469 scoped_ptr<uint8[]> info_tracks; |
1364 int info_tracks_size = 0; | 1470 int info_tracks_size = 0; |
1365 CreateInitSegment(true, true, false, false, &info_tracks, &info_tracks_size); | 1471 CreateInitSegment(true, true, false, |
| 1472 false, false, &info_tracks, &info_tracks_size); |
1366 | 1473 |
1367 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); | 1474 scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster()); |
1368 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); | 1475 scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster()); |
1369 | 1476 |
1370 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); | 1477 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); |
1371 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); | 1478 scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); |
1372 uint8* dst = buffer.get(); | 1479 uint8* dst = buffer.get(); |
1373 memcpy(dst, info_tracks.get(), info_tracks_size); | 1480 memcpy(dst, info_tracks.get(), info_tracks_size); |
1374 dst += info_tracks_size; | 1481 dst += info_tracks_size; |
1375 | 1482 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 message_loop_.RunUntilIdle(); | 1624 message_loop_.RunUntilIdle(); |
1518 | 1625 |
1519 EXPECT_TRUE(audio_read_done); | 1626 EXPECT_TRUE(audio_read_done); |
1520 EXPECT_TRUE(video_read_done); | 1627 EXPECT_TRUE(video_read_done); |
1521 } | 1628 } |
1522 | 1629 |
1523 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { | 1630 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { |
1524 EXPECT_CALL(*this, DemuxerOpened()); | 1631 EXPECT_CALL(*this, DemuxerOpened()); |
1525 demuxer_->Initialize( | 1632 demuxer_->Initialize( |
1526 &host_, CreateInitDoneCB( | 1633 &host_, CreateInitDoneCB( |
1527 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN)); | 1634 kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1528 | 1635 |
1529 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 1636 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
1530 | 1637 |
1531 uint8 tmp = 0; | 1638 uint8 tmp = 0; |
1532 demuxer_->AppendData(kSourceId, &tmp, 1); | 1639 demuxer_->AppendData(kSourceId, &tmp, 1); |
1533 } | 1640 } |
1534 | 1641 |
1535 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { | 1642 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { |
1536 EXPECT_CALL(*this, DemuxerOpened()); | 1643 EXPECT_CALL(*this, DemuxerOpened()); |
1537 demuxer_->Initialize( | 1644 demuxer_->Initialize( |
1538 &host_, CreateInitDoneCB(kNoTimestamp(), | 1645 &host_, CreateInitDoneCB(kNoTimestamp(), |
1539 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1646 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1540 | 1647 |
1541 std::vector<std::string> codecs(1); | 1648 std::vector<std::string> codecs(1); |
1542 codecs[0] = "vorbis"; | 1649 codecs[0] = "vorbis"; |
1543 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 1650 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
1544 ChunkDemuxer::kOk); | 1651 ChunkDemuxer::kOk); |
1545 | 1652 |
1546 AppendInitSegment(true, true); | 1653 AppendInitSegment(true, true); |
1547 } | 1654 } |
1548 | 1655 |
1549 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { | 1656 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { |
1550 EXPECT_CALL(*this, DemuxerOpened()); | 1657 EXPECT_CALL(*this, DemuxerOpened()); |
1551 demuxer_->Initialize( | 1658 demuxer_->Initialize( |
1552 &host_, CreateInitDoneCB(kNoTimestamp(), | 1659 &host_, CreateInitDoneCB(kNoTimestamp(), |
1553 DEMUXER_ERROR_COULD_NOT_OPEN)); | 1660 DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1554 | 1661 |
1555 std::vector<std::string> codecs(1); | 1662 std::vector<std::string> codecs(1); |
1556 codecs[0] = "vp8"; | 1663 codecs[0] = "vp8"; |
1557 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1664 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
1558 ChunkDemuxer::kOk); | 1665 ChunkDemuxer::kOk); |
1559 | 1666 |
1560 AppendInitSegment(true, true); | 1667 AppendInitSegment(true, true); |
1561 } | 1668 } |
1562 | 1669 |
1563 TEST_F(ChunkDemuxerTest, MultipleHeaders) { | 1670 TEST_F(ChunkDemuxerTest, MultipleHeaders) { |
(...skipping 16 matching lines...) Expand all Loading... |
1580 | 1687 |
1581 // Append audio and video data into separate source ids. | 1688 // Append audio and video data into separate source ids. |
1582 AppendCluster(audio_id, | 1689 AppendCluster(audio_id, |
1583 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 1690 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1584 GenerateAudioStreamExpectedReads(0, 4); | 1691 GenerateAudioStreamExpectedReads(0, 4); |
1585 AppendCluster(video_id, | 1692 AppendCluster(video_id, |
1586 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 1693 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1587 GenerateVideoStreamExpectedReads(0, 4); | 1694 GenerateVideoStreamExpectedReads(0, 4); |
1588 } | 1695 } |
1589 | 1696 |
| 1697 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) { |
| 1698 // TODO(matthewjheaney): Here and elsewhere, we need more tests |
| 1699 // for inband text tracks (http://crbug/321455). |
| 1700 |
| 1701 std::string audio_id = "audio1"; |
| 1702 std::string video_id = "video1"; |
| 1703 |
| 1704 EXPECT_CALL(host_, AddTextStream(_,_)) |
| 1705 .Times(Exactly(2)); |
| 1706 ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, true)); |
| 1707 |
| 1708 // Append audio and video data into separate source ids. |
| 1709 AppendCluster(audio_id, |
| 1710 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
| 1711 GenerateAudioStreamExpectedReads(0, 4); |
| 1712 AppendCluster(video_id, |
| 1713 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
| 1714 GenerateVideoStreamExpectedReads(0, 4); |
| 1715 } |
| 1716 |
1590 TEST_F(ChunkDemuxerTest, AddIdFailures) { | 1717 TEST_F(ChunkDemuxerTest, AddIdFailures) { |
1591 EXPECT_CALL(*this, DemuxerOpened()); | 1718 EXPECT_CALL(*this, DemuxerOpened()); |
1592 demuxer_->Initialize( | 1719 demuxer_->Initialize( |
1593 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1720 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1594 | 1721 |
1595 std::string audio_id = "audio1"; | 1722 std::string audio_id = "audio1"; |
1596 std::string video_id = "video1"; | 1723 std::string video_id = "video1"; |
1597 | 1724 |
1598 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); | 1725 ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk); |
1599 | 1726 |
1600 // Adding an id with audio/video should fail because we already added audio. | 1727 // Adding an id with audio/video should fail because we already added audio. |
1601 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); | 1728 ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit); |
1602 | 1729 |
1603 AppendInitSegmentWithSourceId(audio_id, true, false); | 1730 AppendInitSegmentWithSourceId(audio_id, true, false, false); |
1604 | 1731 |
1605 // Adding an id after append should fail. | 1732 // Adding an id after append should fail. |
1606 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); | 1733 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); |
1607 } | 1734 } |
1608 | 1735 |
1609 // Test that Read() calls after a RemoveId() return "end of stream" buffers. | 1736 // Test that Read() calls after a RemoveId() return "end of stream" buffers. |
1610 TEST_F(ChunkDemuxerTest, RemoveId) { | 1737 TEST_F(ChunkDemuxerTest, RemoveId) { |
1611 std::string audio_id = "audio1"; | 1738 std::string audio_id = "audio1"; |
1612 std::string video_id = "video1"; | 1739 std::string video_id = "video1"; |
1613 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1740 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 | 1949 |
1823 EXPECT_TRUE(seek_cb_was_called); | 1950 EXPECT_TRUE(seek_cb_was_called); |
1824 | 1951 |
1825 ShutdownDemuxer(); | 1952 ShutdownDemuxer(); |
1826 } | 1953 } |
1827 | 1954 |
1828 // Test ranges in an audio-only stream. | 1955 // Test ranges in an audio-only stream. |
1829 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 1956 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
1830 EXPECT_CALL(*this, DemuxerOpened()); | 1957 EXPECT_CALL(*this, DemuxerOpened()); |
1831 demuxer_->Initialize( | 1958 demuxer_->Initialize( |
1832 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1959 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1833 | 1960 |
1834 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 1961 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); |
1835 AppendInitSegment(true, false); | 1962 AppendInitSegment(true, false); |
1836 | 1963 |
1837 // Test a simple cluster. | 1964 // Test a simple cluster. |
1838 AppendCluster( | 1965 AppendCluster( |
1839 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); | 1966 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1840 | 1967 |
1841 CheckExpectedRanges("{ [0,92) }"); | 1968 CheckExpectedRanges("{ [0,92) }"); |
1842 | 1969 |
1843 // Append a disjoint cluster to check for two separate ranges. | 1970 // Append a disjoint cluster to check for two separate ranges. |
1844 AppendCluster(GenerateSingleStreamCluster( | 1971 AppendCluster(GenerateSingleStreamCluster( |
1845 150, 219, kAudioTrackNum, kAudioBlockDuration)); | 1972 150, 219, kAudioTrackNum, kAudioBlockDuration)); |
1846 | 1973 |
1847 CheckExpectedRanges("{ [0,92) [150,219) }"); | 1974 CheckExpectedRanges("{ [0,92) [150,219) }"); |
1848 } | 1975 } |
1849 | 1976 |
1850 // Test ranges in a video-only stream. | 1977 // Test ranges in a video-only stream. |
1851 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 1978 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
1852 EXPECT_CALL(*this, DemuxerOpened()); | 1979 EXPECT_CALL(*this, DemuxerOpened()); |
1853 demuxer_->Initialize( | 1980 demuxer_->Initialize( |
1854 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1981 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true); |
1855 | 1982 |
1856 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 1983 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); |
1857 AppendInitSegment(false, true); | 1984 AppendInitSegment(false, true); |
1858 | 1985 |
1859 // Test a simple cluster. | 1986 // Test a simple cluster. |
1860 AppendCluster( | 1987 AppendCluster( |
1861 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); | 1988 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1862 | 1989 |
1863 CheckExpectedRanges("{ [0,132) }"); | 1990 CheckExpectedRanges("{ [0,132) }"); |
1864 | 1991 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2086 EXPECT_EQ(DemuxerStream::kOk, status); | 2213 EXPECT_EQ(DemuxerStream::kOk, status); |
2087 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); | 2214 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); |
2088 | 2215 |
2089 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 2216 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
2090 EXPECT_EQ(DemuxerStream::kOk, status); | 2217 EXPECT_EQ(DemuxerStream::kOk, status); |
2091 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); | 2218 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); |
2092 } | 2219 } |
2093 | 2220 |
2094 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { | 2221 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { |
2095 EXPECT_CALL(*this, DemuxerOpened()); | 2222 EXPECT_CALL(*this, DemuxerOpened()); |
2096 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK)); | 2223 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true); |
2097 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); | 2224 ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk); |
2098 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); | 2225 ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk); |
2099 | 2226 |
2100 CheckExpectedRanges("audio", "{ }"); | 2227 CheckExpectedRanges("audio", "{ }"); |
2101 CheckExpectedRanges("video", "{ }"); | 2228 CheckExpectedRanges("video", "{ }"); |
2102 } | 2229 } |
2103 | 2230 |
2104 // Test that Seek() completes successfully when the first cluster | 2231 // Test that Seek() completes successfully when the first cluster |
2105 // arrives. | 2232 // arrives. |
2106 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { | 2233 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2410 AppendCluster(kDefaultSecondCluster()); | 2537 AppendCluster(kDefaultSecondCluster()); |
2411 MarkEndOfStream(PIPELINE_OK); | 2538 MarkEndOfStream(PIPELINE_OK); |
2412 } | 2539 } |
2413 | 2540 |
2414 // Test receiving a Shutdown() call before we get an Initialize() | 2541 // Test receiving a Shutdown() call before we get an Initialize() |
2415 // call. This can happen if video element gets destroyed before | 2542 // call. This can happen if video element gets destroyed before |
2416 // the pipeline has a chance to initialize the demuxer. | 2543 // the pipeline has a chance to initialize the demuxer. |
2417 TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) { | 2544 TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) { |
2418 demuxer_->Shutdown(); | 2545 demuxer_->Shutdown(); |
2419 demuxer_->Initialize( | 2546 demuxer_->Initialize( |
2420 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 2547 &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true); |
2421 message_loop_.RunUntilIdle(); | 2548 message_loop_.RunUntilIdle(); |
2422 } | 2549 } |
2423 | 2550 |
2424 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { | 2551 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) { |
2425 ASSERT_TRUE(InitDemuxer(true, true)); | 2552 ASSERT_TRUE(InitDemuxer(true, true)); |
2426 AppendCluster(kDefaultFirstCluster()); | 2553 AppendCluster(kDefaultFirstCluster()); |
2427 | 2554 |
2428 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 2555 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
2429 ASSERT_TRUE(stream); | 2556 ASSERT_TRUE(stream); |
2430 | 2557 |
(...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 | 2686 // NOTE: The current GC algorithm tries to preserve the GOP at the |
2560 // current position as well as the last appended GOP. This is | 2687 // current position as well as the last appended GOP. This is |
2561 // why there are 2 ranges in the expectations. | 2688 // why there are 2 ranges in the expectations. |
2562 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); | 2689 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5); |
2563 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); | 2690 CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }"); |
2564 } | 2691 } |
2565 | 2692 |
2566 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { | 2693 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) { |
2567 EXPECT_CALL(*this, DemuxerOpened()); | 2694 EXPECT_CALL(*this, DemuxerOpened()); |
2568 demuxer_->Initialize( | 2695 demuxer_->Initialize( |
2569 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK)); | 2696 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true); |
2570 | 2697 |
2571 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); | 2698 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); |
2572 | 2699 |
2573 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), | 2700 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), |
2574 base::TimeDelta::FromMilliseconds(1)); | 2701 base::TimeDelta::FromMilliseconds(1)); |
2575 } | 2702 } |
2576 | 2703 |
2577 TEST_F(ChunkDemuxerTest, AppendWindow) { | 2704 TEST_F(ChunkDemuxerTest, AppendWindow) { |
2578 ASSERT_TRUE(InitDemuxer(false, true)); | 2705 ASSERT_TRUE(InitDemuxer(false, true)); |
2579 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 2706 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
(...skipping 27 matching lines...) Expand all Loading... |
2607 | 2734 |
2608 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { | 2735 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { |
2609 ASSERT_TRUE(InitDemuxer(true, true)); | 2736 ASSERT_TRUE(InitDemuxer(true, true)); |
2610 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 2737 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
2611 AppendGarbage(); | 2738 AppendGarbage(); |
2612 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); | 2739 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50); |
2613 demuxer_->StartWaitingForSeek(seek_time); | 2740 demuxer_->StartWaitingForSeek(seek_time); |
2614 } | 2741 } |
2615 | 2742 |
2616 } // namespace media | 2743 } // namespace media |
OLD | NEW |