| 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 |