Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "media/base/audio_decoder_config.h" | 6 #include "media/base/audio_decoder_config.h" |
| 7 #include "media/base/mock_callback.h" | 7 #include "media/base/mock_callback.h" |
| 8 #include "media/base/mock_demuxer_host.h" | 8 #include "media/base/mock_demuxer_host.h" |
| 9 #include "media/base/test_data_util.h" | 9 #include "media/base/test_data_util.h" |
| 10 #include "media/filters/chunk_demuxer.h" | 10 #include "media/filters/chunk_demuxer.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at | 32 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at |
| 33 // index 1 and spans 8 bytes. | 33 // index 1 and spans 8 bytes. |
| 34 static const int kVideoTrackSizeOffset = 1; | 34 static const int kVideoTrackSizeOffset = 1; |
| 35 static const int kVideoTrackSizeWidth = 8; | 35 static const int kVideoTrackSizeWidth = 8; |
| 36 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + | 36 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + |
| 37 kVideoTrackSizeWidth; | 37 kVideoTrackSizeWidth; |
| 38 | 38 |
| 39 static const int kVideoTrackNum = 1; | 39 static const int kVideoTrackNum = 1; |
| 40 static const int kAudioTrackNum = 2; | 40 static const int kAudioTrackNum = 2; |
| 41 | 41 |
| 42 static const int kAudioBlockDuration = 23; | |
| 43 static const int kVideoBlockDuration = 33; | |
| 44 | |
| 42 static const char* kSourceId = "SourceId"; | 45 static const char* kSourceId = "SourceId"; |
| 43 | 46 |
| 44 base::TimeDelta kDefaultDuration() { | 47 base::TimeDelta kDefaultDuration() { |
| 45 return base::TimeDelta::FromMilliseconds(201224); | 48 return base::TimeDelta::FromMilliseconds(201224); |
| 46 } | 49 } |
| 47 | 50 |
| 48 // Write an integer into buffer in the form of vint that spans 8 bytes. | 51 // Write an integer into buffer in the form of vint that spans 8 bytes. |
| 49 // The data pointed by |buffer| should be at least 8 bytes long. | 52 // The data pointed by |buffer| should be at least 8 bytes long. |
| 50 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF. | 53 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF. |
| 51 static void WriteInt64(uint8* buffer, int64 number) { | 54 static void WriteInt64(uint8* buffer, int64 number) { |
| 52 DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF)); | 55 DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF)); |
| 53 buffer[0] = 0x01; | 56 buffer[0] = 0x01; |
| 54 int64 tmp = number; | 57 int64 tmp = number; |
| 55 for (int i = 7; i > 0; i--) { | 58 for (int i = 7; i > 0; i--) { |
| 56 buffer[i] = tmp & 0xff; | 59 buffer[i] = tmp & 0xff; |
| 57 tmp >>= 8; | 60 tmp >>= 8; |
| 58 } | 61 } |
| 59 } | 62 } |
| 60 | 63 |
| 61 MATCHER_P(HasTimestamp, timestamp_in_ms, "") { | 64 MATCHER_P(HasTimestamp, timestamp_in_ms, "") { |
| 62 return !arg->IsEndOfStream() && | 65 return arg && !arg->IsEndOfStream() && |
| 63 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms; | 66 arg->GetTimestamp().InMilliseconds() == timestamp_in_ms; |
| 64 } | 67 } |
| 65 | 68 |
| 66 static void OnReadDone(const base::TimeDelta& expected_time, | 69 static void OnReadDone(const base::TimeDelta& expected_time, |
| 67 bool* called, | 70 bool* called, |
| 68 const scoped_refptr<Buffer>& buffer) { | 71 const scoped_refptr<Buffer>& buffer) { |
| 69 EXPECT_EQ(expected_time, buffer->GetTimestamp()); | 72 EXPECT_EQ(expected_time, buffer->GetTimestamp()); |
| 70 *called = true; | 73 *called = true; |
| 71 } | 74 } |
| 72 | 75 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 } | 173 } |
| 171 | 174 |
| 172 ChunkDemuxer::Status AddId() { | 175 ChunkDemuxer::Status AddId() { |
| 173 std::vector<std::string> codecs(2); | 176 std::vector<std::string> codecs(2); |
| 174 codecs[0] = "vp8"; | 177 codecs[0] = "vp8"; |
| 175 codecs[1] = "vorbis"; | 178 codecs[1] = "vorbis"; |
| 176 return demuxer_->AddId(kSourceId, "video/webm", codecs); | 179 return demuxer_->AddId(kSourceId, "video/webm", codecs); |
| 177 } | 180 } |
| 178 | 181 |
| 179 bool AppendData(const uint8* data, size_t length) { | 182 bool AppendData(const uint8* data, size_t length) { |
| 183 if (!length) { | |
| 184 LOG(ERROR) << "Test code tried to append a zero length buffer!"; | |
|
scherkus (not reviewing)
2012/05/17 02:45:46
NOTREACHED() / LOG(FATAL) / CHECK() instead?
acolwell GONE FROM CHROMIUM
2012/05/17 18:28:51
Done.
| |
| 185 return false; | |
| 186 } | |
| 187 | |
| 180 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); | 188 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); |
| 181 EXPECT_CALL(host_, SetNetworkActivity(true)) | 189 EXPECT_CALL(host_, SetNetworkActivity(true)) |
| 182 .Times(AnyNumber()); | 190 .Times(AnyNumber()); |
| 183 return demuxer_->AppendData(kSourceId, data, length); | 191 return demuxer_->AppendData(kSourceId, data, length); |
| 184 } | 192 } |
| 185 | 193 |
| 186 bool AppendDataInPieces(const uint8* data, size_t length) { | 194 bool AppendDataInPieces(const uint8* data, size_t length) { |
| 187 return AppendDataInPieces(data, length, 7); | 195 return AppendDataInPieces(data, length, 7); |
| 188 } | 196 } |
| 189 | 197 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 EXPECT_CALL(*client_, DemuxerClosed()); | 254 EXPECT_CALL(*client_, DemuxerClosed()); |
| 247 demuxer_->Shutdown(); | 255 demuxer_->Shutdown(); |
| 248 } | 256 } |
| 249 } | 257 } |
| 250 | 258 |
| 251 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { | 259 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { |
| 252 uint8 data[] = { 0x00 }; | 260 uint8 data[] = { 0x00 }; |
| 253 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); | 261 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); |
| 254 } | 262 } |
| 255 | 263 |
| 256 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode, | 264 scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) { |
| 257 int size) { | 265 CHECK_GT(block_count, 0); |
| 266 | |
| 267 int size = 10; | |
| 258 scoped_array<uint8> data(new uint8[size]); | 268 scoped_array<uint8> data(new uint8[size]); |
| 259 cb->AddSimpleBlock(track_num, timecode, 0, data.get(), size); | 269 |
| 270 ClusterBuilder cb; | |
| 271 cb.SetClusterTimecode(timecode); | |
| 272 int audio_timecode = timecode; | |
| 273 int video_timecode = timecode + 1; | |
| 274 | |
| 275 if (block_count == 1) { | |
| 276 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0, | |
| 277 data.get(), size); | |
| 278 return cb.Finish(); | |
| 279 } | |
| 280 | |
| 281 // Create simple blocks for everything except the last 2 blocks. | |
| 282 for (int i = 0; i < block_count - 2; i++) { | |
| 283 if (audio_timecode <= video_timecode) { | |
| 284 cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, 0, data.get(), size); | |
| 285 audio_timecode += kAudioBlockDuration; | |
| 286 continue; | |
| 287 } | |
| 288 | |
| 289 cb.AddSimpleBlock(kVideoTrackNum, video_timecode, 0, data.get(), size); | |
| 290 video_timecode += kVideoBlockDuration; | |
| 291 } | |
| 292 | |
| 293 // Make the last 2 blocks BlockGroups so that they don't get delayed by the | |
| 294 // block duration calculation logic. | |
| 295 if (audio_timecode <= video_timecode) { | |
| 296 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0, | |
| 297 data.get(), size); | |
| 298 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, 0, | |
| 299 data.get(), size); | |
| 300 } else { | |
| 301 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, 0, | |
| 302 data.get(), size); | |
| 303 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0, | |
| 304 data.get(), size); | |
| 305 } | |
| 306 | |
| 307 return cb.Finish(); | |
| 308 } | |
| 309 | |
| 310 void GenerateExpectedReads(int timecode, int block_count, | |
| 311 DemuxerStream* audio, | |
| 312 DemuxerStream* video) { | |
| 313 CHECK_GT(block_count, 0); | |
| 314 int audio_timecode = timecode; | |
| 315 int video_timecode = timecode + 1; | |
| 316 | |
| 317 if (block_count == 1) { | |
| 318 ExpectRead(audio, audio_timecode); | |
| 319 return; | |
| 320 } | |
| 321 | |
| 322 for (int i = 0; i < block_count; i++) { | |
| 323 if (audio_timecode <= video_timecode) { | |
| 324 ExpectRead(audio, audio_timecode); | |
| 325 audio_timecode += kAudioBlockDuration; | |
| 326 continue; | |
| 327 } | |
| 328 | |
| 329 ExpectRead(video, video_timecode); | |
| 330 video_timecode += kVideoBlockDuration; | |
| 331 } | |
| 260 } | 332 } |
| 261 | 333 |
| 262 MOCK_METHOD1(ReadDone, void(const scoped_refptr<Buffer>&)); | 334 MOCK_METHOD1(ReadDone, void(const scoped_refptr<Buffer>&)); |
| 263 | 335 |
| 264 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { | 336 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { |
| 265 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); | 337 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); |
| 266 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, | 338 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, |
| 267 base::Unretained(this))); | 339 base::Unretained(this))); |
| 268 } | 340 } |
| 269 | 341 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 | 481 |
| 410 InSequence s; | 482 InSequence s; |
| 411 | 483 |
| 412 EXPECT_CALL(*this, Checkpoint(1)); | 484 EXPECT_CALL(*this, Checkpoint(1)); |
| 413 | 485 |
| 414 demuxer_->Seek(base::TimeDelta::FromSeconds(0), | 486 demuxer_->Seek(base::TimeDelta::FromSeconds(0), |
| 415 NewExpectedStatusCB(PIPELINE_OK)); | 487 NewExpectedStatusCB(PIPELINE_OK)); |
| 416 | 488 |
| 417 EXPECT_CALL(*this, Checkpoint(2)); | 489 EXPECT_CALL(*this, Checkpoint(2)); |
| 418 | 490 |
| 419 ClusterBuilder cb; | 491 scoped_ptr<Cluster> cluster(GenerateCluster(0, 4)); |
| 420 cb.SetClusterTimecode(0); | |
| 421 AddSimpleBlock(&cb, kVideoTrackNum, 0); | |
| 422 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 423 | 492 |
| 424 Checkpoint(1); | 493 Checkpoint(1); |
| 425 | 494 |
| 426 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 495 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 427 | 496 |
| 428 Checkpoint(2); | 497 Checkpoint(2); |
| 429 } | 498 } |
| 430 | 499 |
| 431 // Test the case where a Seek() is requested while the parser | 500 // Test the case where a Seek() is requested while the parser |
| 432 // is in the middle of cluster. This is to verify that the parser | 501 // is in the middle of cluster. This is to verify that the parser |
| 433 // resets itself on seek and is in the right state when data from | 502 // resets itself on seek and is in the right state when data from |
| 434 // the new seek point arrives. | 503 // the new seek point arrives. |
| 435 TEST_F(ChunkDemuxerTest, TestSeekWhileParsingCluster) { | 504 TEST_F(ChunkDemuxerTest, TestSeekWhileParsingCluster) { |
| 436 ASSERT_TRUE(InitDemuxer(true, true, false)); | 505 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 437 | 506 |
| 438 scoped_refptr<DemuxerStream> audio = | 507 scoped_refptr<DemuxerStream> audio = |
| 439 demuxer_->GetStream(DemuxerStream::AUDIO); | 508 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 440 scoped_refptr<DemuxerStream> video = | 509 scoped_refptr<DemuxerStream> video = |
| 441 demuxer_->GetStream(DemuxerStream::VIDEO); | 510 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 442 | 511 |
| 443 InSequence s; | 512 InSequence s; |
| 444 | 513 |
| 445 ClusterBuilder cb; | 514 scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6)); |
| 446 cb.SetClusterTimecode(0); | 515 scoped_ptr<Cluster> cluster_b(GenerateCluster(5000, 6)); |
| 447 AddSimpleBlock(&cb, kAudioTrackNum, 1); | |
| 448 AddSimpleBlock(&cb, kVideoTrackNum, 2); | |
| 449 AddSimpleBlock(&cb, kAudioTrackNum, 10); | |
| 450 AddSimpleBlock(&cb, kVideoTrackNum, 20); | |
| 451 scoped_ptr<Cluster> cluster_a(cb.Finish()); | |
| 452 | |
| 453 cb.SetClusterTimecode(5000); | |
| 454 AddSimpleBlock(&cb, kAudioTrackNum, 5000); | |
| 455 AddSimpleBlock(&cb, kVideoTrackNum, 5005); | |
| 456 AddSimpleBlock(&cb, kAudioTrackNum, 5007); | |
| 457 AddSimpleBlock(&cb, kVideoTrackNum, 5035); | |
| 458 scoped_ptr<Cluster> cluster_b(cb.Finish()); | |
| 459 | 516 |
| 460 // Append all but the last byte so that everything but | 517 // Append all but the last byte so that everything but |
| 461 // the last block can be parsed. | 518 // the last block can be parsed. |
| 462 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size() - 1)); | 519 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size() - 1)); |
| 463 | 520 |
| 464 ExpectRead(audio, 1); | 521 ExpectRead(audio, 0); |
| 465 ExpectRead(video, 2); | 522 ExpectRead(video, 1); |
| 466 ExpectRead(audio, 10); | 523 ExpectRead(audio, kAudioBlockDuration); |
| 524 // Note: We skip trying to read a video buffer here because computing | |
| 525 // the duration for this block relies on successfully parsing the last block | |
| 526 // in the cluster the cluster. | |
| 527 ExpectRead(audio, 2 * kAudioBlockDuration); | |
| 467 | 528 |
| 468 demuxer_->FlushData(); | 529 demuxer_->FlushData(); |
| 469 demuxer_->Seek(base::TimeDelta::FromSeconds(5), | 530 demuxer_->Seek(base::TimeDelta::FromSeconds(5), |
| 470 NewExpectedStatusCB(PIPELINE_OK)); | 531 NewExpectedStatusCB(PIPELINE_OK)); |
| 471 | 532 |
| 472 | 533 |
| 473 // Append the new cluster and verify that only the blocks | 534 // Append the new cluster and verify that only the blocks |
| 474 // in the new cluster are returned. | 535 // in the new cluster are returned. |
| 475 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); | 536 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); |
| 476 ExpectRead(audio, 5000); | 537 GenerateExpectedReads(5000, 6, audio, video); |
| 477 ExpectRead(video, 5005); | |
| 478 ExpectRead(audio, 5007); | |
| 479 ExpectRead(video, 5035); | |
| 480 } | 538 } |
| 481 | 539 |
| 482 // Test the case where AppendData() is called before Init(). | 540 // Test the case where AppendData() is called before Init(). |
| 483 TEST_F(ChunkDemuxerTest, TestAppendDataBeforeInit) { | 541 TEST_F(ChunkDemuxerTest, TestAppendDataBeforeInit) { |
| 484 scoped_array<uint8> info_tracks; | 542 scoped_array<uint8> info_tracks; |
| 485 int info_tracks_size = 0; | 543 int info_tracks_size = 0; |
| 486 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); | 544 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); |
| 487 | 545 |
| 488 EXPECT_FALSE(demuxer_->AppendData(kSourceId, info_tracks.get(), | 546 EXPECT_FALSE(demuxer_->AppendData(kSourceId, info_tracks.get(), |
| 489 info_tracks_size)); | 547 info_tracks_size)); |
| 490 } | 548 } |
| 491 | 549 |
| 492 // Make sure Read() callbacks are dispatched with the proper data. | 550 // Make sure Read() callbacks are dispatched with the proper data. |
| 493 TEST_F(ChunkDemuxerTest, TestRead) { | 551 TEST_F(ChunkDemuxerTest, TestRead) { |
| 494 ASSERT_TRUE(InitDemuxer(true, true, false)); | 552 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 495 | 553 |
| 496 scoped_refptr<DemuxerStream> audio = | 554 scoped_refptr<DemuxerStream> audio = |
| 497 demuxer_->GetStream(DemuxerStream::AUDIO); | 555 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 498 scoped_refptr<DemuxerStream> video = | 556 scoped_refptr<DemuxerStream> video = |
| 499 demuxer_->GetStream(DemuxerStream::VIDEO); | 557 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 500 | 558 |
| 501 bool audio_read_done = false; | 559 bool audio_read_done = false; |
| 502 bool video_read_done = false; | 560 bool video_read_done = false; |
| 503 audio->Read(base::Bind(&OnReadDone, | 561 audio->Read(base::Bind(&OnReadDone, |
| 504 base::TimeDelta::FromMilliseconds(32), | 562 base::TimeDelta::FromMilliseconds(0), |
| 505 &audio_read_done)); | 563 &audio_read_done)); |
| 506 | 564 |
| 507 video->Read(base::Bind(&OnReadDone, | 565 video->Read(base::Bind(&OnReadDone, |
| 508 base::TimeDelta::FromMilliseconds(123), | 566 base::TimeDelta::FromMilliseconds(1), |
| 509 &video_read_done)); | 567 &video_read_done)); |
| 510 | 568 |
| 511 ClusterBuilder cb; | 569 scoped_ptr<Cluster> cluster(GenerateCluster(0, 4)); |
| 512 cb.SetClusterTimecode(0); | |
| 513 AddSimpleBlock(&cb, kAudioTrackNum, 32); | |
| 514 AddSimpleBlock(&cb, kVideoTrackNum, 123); | |
| 515 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 516 | 570 |
| 517 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 571 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 518 | 572 |
| 519 EXPECT_TRUE(audio_read_done); | 573 EXPECT_TRUE(audio_read_done); |
| 520 EXPECT_TRUE(video_read_done); | 574 EXPECT_TRUE(video_read_done); |
| 521 } | 575 } |
| 522 | 576 |
| 523 TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) { | 577 TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) { |
| 524 ASSERT_TRUE(InitDemuxer(true, true, false)); | 578 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 525 | 579 |
| 526 ClusterBuilder cb; | 580 scoped_ptr<Cluster> cluster_a(GenerateCluster(10, 4)); |
| 527 | |
| 528 cb.SetClusterTimecode(10); | |
| 529 AddSimpleBlock(&cb, kAudioTrackNum, 10); | |
| 530 AddSimpleBlock(&cb, kVideoTrackNum, 10); | |
| 531 AddSimpleBlock(&cb, kAudioTrackNum, 33); | |
| 532 AddSimpleBlock(&cb, kVideoTrackNum, 43); | |
| 533 scoped_ptr<Cluster> cluster_a(cb.Finish()); | |
| 534 | 581 |
| 535 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 582 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 536 | 583 |
| 537 // Cluster B starts before cluster_a and has data | 584 // Cluster B starts before cluster_a and has data |
| 538 // that overlaps. | 585 // that overlaps. |
| 539 cb.SetClusterTimecode(5); | 586 scoped_ptr<Cluster> cluster_b(GenerateCluster(5, 4)); |
| 540 AddSimpleBlock(&cb, kAudioTrackNum, 5); | |
| 541 AddSimpleBlock(&cb, kVideoTrackNum, 7); | |
| 542 AddSimpleBlock(&cb, kAudioTrackNum, 28); | |
| 543 AddSimpleBlock(&cb, kVideoTrackNum, 40); | |
| 544 scoped_ptr<Cluster> cluster_b(cb.Finish()); | |
| 545 | 587 |
| 546 // Make sure that AppendData() fails because this cluster data | 588 // Make sure that AppendData() fails because this cluster data |
| 547 // is before previous data. | 589 // is before previous data. |
| 548 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 590 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 549 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); | 591 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); |
| 550 | 592 |
| 551 // Verify that AppendData() doesn't accept more data now. | 593 // Verify that AppendData() doesn't accept more data now. |
| 552 cb.SetClusterTimecode(45); | 594 scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2)); |
| 553 AddSimpleBlock(&cb, kAudioTrackNum, 45); | |
| 554 AddSimpleBlock(&cb, kVideoTrackNum, 45); | |
| 555 scoped_ptr<Cluster> cluster_c(cb.Finish()); | |
| 556 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(), | 595 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(), |
| 557 cluster_c->size())); | 596 cluster_c->size())); |
| 558 } | 597 } |
| 559 | 598 |
| 560 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { | 599 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { |
| 561 ASSERT_TRUE(InitDemuxer(true, true, false)); | 600 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 562 | 601 |
| 563 ClusterBuilder cb; | 602 ClusterBuilder cb; |
| 564 | 603 |
| 565 // Test the case where block timecodes are not monotonically | 604 // Test the case where block timecodes are not monotonically |
| 566 // increasing but stay above the cluster timecode. | 605 // increasing but stay above the cluster timecode. |
| 567 cb.SetClusterTimecode(5); | 606 cb.SetClusterTimecode(5); |
| 568 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 607 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 569 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 608 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
| 570 AddSimpleBlock(&cb, kAudioTrackNum, 7); | 609 AddSimpleBlock(&cb, kAudioTrackNum, 7); |
| 571 AddSimpleBlock(&cb, kVideoTrackNum, 15); | 610 AddSimpleBlock(&cb, kVideoTrackNum, 15); |
| 572 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 611 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| 573 | 612 |
| 574 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 613 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 575 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 614 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 576 | 615 |
| 577 // Verify that AppendData() doesn't accept more data now. | 616 // Verify that AppendData() doesn't accept more data now. |
| 578 cb.SetClusterTimecode(20); | 617 scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2)); |
| 579 AddSimpleBlock(&cb, kAudioTrackNum, 20); | |
| 580 AddSimpleBlock(&cb, kVideoTrackNum, 20); | |
| 581 scoped_ptr<Cluster> cluster_b(cb.Finish()); | |
| 582 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(), | 618 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(), |
| 583 cluster_b->size())); | 619 cluster_b->size())); |
| 584 } | 620 } |
| 585 | 621 |
| 586 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { | 622 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { |
| 587 ASSERT_TRUE(InitDemuxer(true, true, false)); | 623 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 588 | 624 |
| 589 ClusterBuilder cb; | 625 ClusterBuilder cb; |
| 590 | 626 |
| 591 // Test timecodes going backwards and including values less than the cluster | 627 // Test timecodes going backwards and including values less than the cluster |
| 592 // timecode. | 628 // timecode. |
| 593 cb.SetClusterTimecode(5); | 629 cb.SetClusterTimecode(5); |
| 594 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 630 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 595 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 631 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
| 596 AddSimpleBlock(&cb, kAudioTrackNum, 3); | 632 AddSimpleBlock(&cb, kAudioTrackNum, 3); |
| 597 AddSimpleBlock(&cb, kVideoTrackNum, 3); | 633 AddSimpleBlock(&cb, kVideoTrackNum, 3); |
| 598 scoped_ptr<Cluster> cluster_a(cb.Finish()); | 634 scoped_ptr<Cluster> cluster_a(cb.Finish()); |
| 599 | 635 |
| 600 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 636 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 601 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 637 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
| 602 | 638 |
| 603 // Verify that AppendData() doesn't accept more data now. | 639 // Verify that AppendData() doesn't accept more data now. |
| 604 cb.SetClusterTimecode(6); | 640 scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2)); |
| 605 AddSimpleBlock(&cb, kAudioTrackNum, 6); | |
| 606 AddSimpleBlock(&cb, kVideoTrackNum, 6); | |
| 607 scoped_ptr<Cluster> cluster_b(cb.Finish()); | |
| 608 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(), | 641 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(), |
| 609 cluster_b->size())); | 642 cluster_b->size())); |
| 610 } | 643 } |
| 611 | 644 |
| 612 | 645 |
| 613 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { | 646 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { |
| 614 ASSERT_TRUE(InitDemuxer(true, true, false)); | 647 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 615 | 648 |
| 616 ClusterBuilder cb; | 649 ClusterBuilder cb; |
| 617 | 650 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 644 | 677 |
| 645 cb.SetClusterTimecode(5); | 678 cb.SetClusterTimecode(5); |
| 646 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 679 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
| 647 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 680 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
| 648 scoped_ptr<Cluster> cluster_b(cb.Finish()); | 681 scoped_ptr<Cluster> cluster_b(cb.Finish()); |
| 649 | 682 |
| 650 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 683 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 651 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); | 684 ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size())); |
| 652 | 685 |
| 653 // Verify that AppendData() doesn't accept more data now. | 686 // Verify that AppendData() doesn't accept more data now. |
| 654 cb.SetClusterTimecode(10); | 687 scoped_ptr<Cluster> cluster_c(GenerateCluster(10, 2)); |
| 655 AddSimpleBlock(&cb, kAudioTrackNum, 10); | |
| 656 AddSimpleBlock(&cb, kVideoTrackNum, 10); | |
| 657 scoped_ptr<Cluster> cluster_c(cb.Finish()); | |
| 658 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(), | 688 EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(), |
| 659 cluster_c->size())); | 689 cluster_c->size())); |
| 660 } | 690 } |
| 661 | 691 |
| 662 // Test the case where a cluster is passed to AppendData() before | 692 // Test the case where a cluster is passed to AppendData() before |
| 663 // INFO & TRACKS data. | 693 // INFO & TRACKS data. |
| 664 TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) { | 694 TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) { |
| 665 EXPECT_CALL(*client_, DemuxerOpened(_)); | 695 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 666 demuxer_->Initialize( | 696 demuxer_->Initialize( |
| 667 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 697 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 668 | 698 |
| 669 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 699 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 670 | 700 |
| 671 ClusterBuilder cb; | 701 scoped_ptr<Cluster> cluster(GenerateCluster(0, 1)); |
| 672 cb.SetClusterTimecode(0); | |
| 673 AddSimpleBlock(&cb, kVideoTrackNum, 0); | |
| 674 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 675 | 702 |
| 676 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 703 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 677 } | 704 } |
| 678 | 705 |
| 679 // Test cases where we get an EndOfStream() call during initialization. | 706 // Test cases where we get an EndOfStream() call during initialization. |
| 680 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { | 707 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
| 681 EXPECT_CALL(*client_, DemuxerOpened(_)); | 708 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 682 demuxer_->Initialize( | 709 demuxer_->Initialize( |
| 683 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 710 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 684 demuxer_->EndOfStream(PIPELINE_OK); | 711 demuxer_->EndOfStream(PIPELINE_OK); |
| 685 } | 712 } |
| 686 | 713 |
| 687 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { | 714 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { |
| 688 ASSERT_TRUE(InitDemuxer(true, true, false)); | 715 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 689 | 716 |
| 690 ClusterBuilder cb; | 717 scoped_ptr<Cluster> cluster(GenerateCluster(0, 4)); |
| 691 cb.SetClusterTimecode(0); | |
| 692 AddSimpleBlock(&cb, kAudioTrackNum, 0); | |
| 693 AddSimpleBlock(&cb, kVideoTrackNum, 0); | |
| 694 AddSimpleBlock(&cb, kAudioTrackNum, 23); | |
| 695 AddSimpleBlock(&cb, kVideoTrackNum, 33); | |
| 696 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 697 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 718 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 698 | 719 |
| 699 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 720 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 700 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); | 721 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); |
| 701 } | 722 } |
| 702 | 723 |
| 703 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { | 724 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { |
| 704 ASSERT_TRUE(InitDemuxer(true, true, false)); | 725 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 705 | 726 |
| 706 ClusterBuilder cb; | 727 scoped_ptr<Cluster> cluster(GenerateCluster(0, 4)); |
| 707 cb.SetClusterTimecode(0); | |
| 708 AddSimpleBlock(&cb, kAudioTrackNum, 0); | |
| 709 AddSimpleBlock(&cb, kVideoTrackNum, 0); | |
| 710 AddSimpleBlock(&cb, kAudioTrackNum, 23); | |
| 711 AddSimpleBlock(&cb, kVideoTrackNum, 33); | |
| 712 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 713 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 728 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 714 | 729 |
| 715 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); | 730 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); |
| 716 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); | 731 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
| 717 } | 732 } |
| 718 | 733 |
| 719 // Helper class to reduce duplicate code when testing end of stream | 734 // Helper class to reduce duplicate code when testing end of stream |
| 720 // Read() behavior. | 735 // Read() behavior. |
| 721 class EndOfStreamHelper { | 736 class EndOfStreamHelper { |
| 722 public: | 737 public: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 demuxer_->GetStream(DemuxerStream::AUDIO); | 788 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 774 scoped_refptr<DemuxerStream> video = | 789 scoped_refptr<DemuxerStream> video = |
| 775 demuxer_->GetStream(DemuxerStream::VIDEO); | 790 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 776 | 791 |
| 777 bool audio_read_done_1 = false; | 792 bool audio_read_done_1 = false; |
| 778 bool video_read_done_1 = false; | 793 bool video_read_done_1 = false; |
| 779 EndOfStreamHelper end_of_stream_helper_1(demuxer_); | 794 EndOfStreamHelper end_of_stream_helper_1(demuxer_); |
| 780 EndOfStreamHelper end_of_stream_helper_2(demuxer_); | 795 EndOfStreamHelper end_of_stream_helper_2(demuxer_); |
| 781 | 796 |
| 782 audio->Read(base::Bind(&OnReadDone, | 797 audio->Read(base::Bind(&OnReadDone, |
| 783 base::TimeDelta::FromMilliseconds(32), | 798 base::TimeDelta::FromMilliseconds(0), |
| 784 &audio_read_done_1)); | 799 &audio_read_done_1)); |
| 785 | 800 |
| 786 video->Read(base::Bind(&OnReadDone, | 801 video->Read(base::Bind(&OnReadDone, |
| 787 base::TimeDelta::FromMilliseconds(123), | 802 base::TimeDelta::FromMilliseconds(1), |
| 788 &video_read_done_1)); | 803 &video_read_done_1)); |
| 789 | 804 |
| 790 end_of_stream_helper_1.RequestReads(); | 805 end_of_stream_helper_1.RequestReads(); |
| 791 end_of_stream_helper_2.RequestReads(); | 806 end_of_stream_helper_2.RequestReads(); |
| 792 | 807 |
| 793 ClusterBuilder cb; | 808 scoped_ptr<Cluster> cluster(GenerateCluster(0, 2)); |
| 794 cb.SetClusterTimecode(0); | |
| 795 AddSimpleBlock(&cb, kAudioTrackNum, 32); | |
| 796 AddSimpleBlock(&cb, kVideoTrackNum, 123); | |
| 797 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 798 | 809 |
| 799 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 810 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 800 | 811 |
| 801 EXPECT_TRUE(audio_read_done_1); | 812 EXPECT_TRUE(audio_read_done_1); |
| 802 EXPECT_TRUE(video_read_done_1); | 813 EXPECT_TRUE(video_read_done_1); |
| 803 end_of_stream_helper_1.CheckIfReadDonesWereCalled(false); | 814 end_of_stream_helper_1.CheckIfReadDonesWereCalled(false); |
| 804 end_of_stream_helper_2.CheckIfReadDonesWereCalled(false); | 815 end_of_stream_helper_2.CheckIfReadDonesWereCalled(false); |
| 805 | 816 |
| 806 demuxer_->EndOfStream(PIPELINE_OK); | 817 demuxer_->EndOfStream(PIPELINE_OK); |
| 807 | 818 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 819 scoped_refptr<DemuxerStream> video = | 830 scoped_refptr<DemuxerStream> video = |
| 820 demuxer_->GetStream(DemuxerStream::VIDEO); | 831 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 821 | 832 |
| 822 bool audio_read_done_1 = false; | 833 bool audio_read_done_1 = false; |
| 823 bool video_read_done_1 = false; | 834 bool video_read_done_1 = false; |
| 824 EndOfStreamHelper end_of_stream_helper_1(demuxer_); | 835 EndOfStreamHelper end_of_stream_helper_1(demuxer_); |
| 825 EndOfStreamHelper end_of_stream_helper_2(demuxer_); | 836 EndOfStreamHelper end_of_stream_helper_2(demuxer_); |
| 826 EndOfStreamHelper end_of_stream_helper_3(demuxer_); | 837 EndOfStreamHelper end_of_stream_helper_3(demuxer_); |
| 827 | 838 |
| 828 audio->Read(base::Bind(&OnReadDone, | 839 audio->Read(base::Bind(&OnReadDone, |
| 829 base::TimeDelta::FromMilliseconds(32), | 840 base::TimeDelta::FromMilliseconds(0), |
| 830 &audio_read_done_1)); | 841 &audio_read_done_1)); |
| 831 | 842 |
| 832 video->Read(base::Bind(&OnReadDone, | 843 video->Read(base::Bind(&OnReadDone, |
| 833 base::TimeDelta::FromMilliseconds(123), | 844 base::TimeDelta::FromMilliseconds(1), |
| 834 &video_read_done_1)); | 845 &video_read_done_1)); |
| 835 | 846 |
| 836 end_of_stream_helper_1.RequestReads(); | 847 end_of_stream_helper_1.RequestReads(); |
| 837 | 848 |
| 838 ClusterBuilder cb; | 849 scoped_ptr<Cluster> cluster(GenerateCluster(0, 2)); |
| 839 cb.SetClusterTimecode(0); | |
| 840 AddSimpleBlock(&cb, kAudioTrackNum, 32); | |
| 841 AddSimpleBlock(&cb, kVideoTrackNum, 123); | |
| 842 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 843 | 850 |
| 844 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 851 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 845 | 852 |
| 846 EXPECT_TRUE(audio_read_done_1); | 853 EXPECT_TRUE(audio_read_done_1); |
| 847 EXPECT_TRUE(video_read_done_1); | 854 EXPECT_TRUE(video_read_done_1); |
| 848 end_of_stream_helper_1.CheckIfReadDonesWereCalled(false); | 855 end_of_stream_helper_1.CheckIfReadDonesWereCalled(false); |
| 849 | 856 |
| 850 demuxer_->EndOfStream(PIPELINE_OK); | 857 demuxer_->EndOfStream(PIPELINE_OK); |
| 851 | 858 |
| 852 end_of_stream_helper_1.CheckIfReadDonesWereCalled(true); | 859 end_of_stream_helper_1.CheckIfReadDonesWereCalled(true); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 866 EXPECT_CALL(*client_, DemuxerOpened(_)); | 873 EXPECT_CALL(*client_, DemuxerOpened(_)); |
| 867 demuxer_->Initialize( | 874 demuxer_->Initialize( |
| 868 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 875 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
| 869 | 876 |
| 870 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 877 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
| 871 | 878 |
| 872 scoped_array<uint8> info_tracks; | 879 scoped_array<uint8> info_tracks; |
| 873 int info_tracks_size = 0; | 880 int info_tracks_size = 0; |
| 874 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); | 881 CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size); |
| 875 | 882 |
| 876 ClusterBuilder cb; | 883 scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 4)); |
| 877 cb.SetClusterTimecode(0); | 884 scoped_ptr<Cluster> cluster_b(GenerateCluster(68, 4)); |
| 878 AddSimpleBlock(&cb, kAudioTrackNum, 32, 512); | |
| 879 AddSimpleBlock(&cb, kVideoTrackNum, 123, 1024); | |
| 880 scoped_ptr<Cluster> cluster_a(cb.Finish()); | |
| 881 | |
| 882 cb.SetClusterTimecode(125); | |
| 883 AddSimpleBlock(&cb, kAudioTrackNum, 125, 2048); | |
| 884 AddSimpleBlock(&cb, kVideoTrackNum, 150, 2048); | |
| 885 scoped_ptr<Cluster> cluster_b(cb.Finish()); | |
| 886 | 885 |
| 887 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); | 886 size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size(); |
| 888 scoped_array<uint8> buffer(new uint8[buffer_size]); | 887 scoped_array<uint8> buffer(new uint8[buffer_size]); |
| 889 uint8* dst = buffer.get(); | 888 uint8* dst = buffer.get(); |
| 890 memcpy(dst, info_tracks.get(), info_tracks_size); | 889 memcpy(dst, info_tracks.get(), info_tracks_size); |
| 891 dst += info_tracks_size; | 890 dst += info_tracks_size; |
| 892 | 891 |
| 893 memcpy(dst, cluster_a->data(), cluster_a->size()); | 892 memcpy(dst, cluster_a->data(), cluster_a->size()); |
| 894 dst += cluster_a->size(); | 893 dst += cluster_a->size(); |
| 895 | 894 |
| 896 memcpy(dst, cluster_b->data(), cluster_b->size()); | 895 memcpy(dst, cluster_b->data(), cluster_b->size()); |
| 897 dst += cluster_b->size(); | 896 dst += cluster_b->size(); |
| 898 | 897 |
| 899 ASSERT_TRUE(AppendDataInPieces(buffer.get(), buffer_size)); | 898 ASSERT_TRUE(AppendDataInPieces(buffer.get(), buffer_size)); |
| 900 | 899 |
| 901 scoped_refptr<DemuxerStream> audio = | 900 scoped_refptr<DemuxerStream> audio = |
| 902 demuxer_->GetStream(DemuxerStream::AUDIO); | 901 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 903 scoped_refptr<DemuxerStream> video = | 902 scoped_refptr<DemuxerStream> video = |
| 904 demuxer_->GetStream(DemuxerStream::VIDEO); | 903 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 905 | 904 |
| 906 ASSERT_TRUE(audio); | 905 ASSERT_TRUE(audio); |
| 907 ASSERT_TRUE(video); | 906 ASSERT_TRUE(video); |
| 908 | 907 |
| 909 bool audio_read_done = false; | 908 GenerateExpectedReads(0, 4, audio, video); |
| 910 bool video_read_done = false; | 909 GenerateExpectedReads(68, 4, audio, video); |
| 911 audio->Read(base::Bind(&OnReadDone, | |
| 912 base::TimeDelta::FromMilliseconds(32), | |
| 913 &audio_read_done)); | |
| 914 | |
| 915 video->Read(base::Bind(&OnReadDone, | |
| 916 base::TimeDelta::FromMilliseconds(123), | |
| 917 &video_read_done)); | |
| 918 | |
| 919 EXPECT_TRUE(audio_read_done); | |
| 920 EXPECT_TRUE(video_read_done); | |
| 921 | |
| 922 audio_read_done = false; | |
| 923 video_read_done = false; | |
| 924 audio->Read(base::Bind(&OnReadDone, | |
| 925 base::TimeDelta::FromMilliseconds(125), | |
| 926 &audio_read_done)); | |
| 927 | |
| 928 video->Read(base::Bind(&OnReadDone, | |
| 929 base::TimeDelta::FromMilliseconds(150), | |
| 930 &video_read_done)); | |
| 931 | |
| 932 EXPECT_TRUE(audio_read_done); | |
| 933 EXPECT_TRUE(video_read_done); | |
| 934 } | 910 } |
| 935 | 911 |
| 936 TEST_F(ChunkDemuxerTest, TestWebMFile_AudioAndVideo) { | 912 TEST_F(ChunkDemuxerTest, TestWebMFile_AudioAndVideo) { |
| 937 struct BufferTimestamps buffer_timestamps[] = { | 913 struct BufferTimestamps buffer_timestamps[] = { |
| 938 {0, 0}, | 914 {0, 0}, |
| 939 {33, 3}, | 915 {33, 3}, |
| 940 {67, 6}, | 916 {67, 6}, |
| 941 {100, 9}, | 917 {100, 9}, |
| 942 {133, 12}, | 918 {133, 12}, |
| 943 {kSkip, kSkip}, | 919 {kSkip, kSkip}, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 }; | 962 }; |
| 987 | 963 |
| 988 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps, | 964 ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps, |
| 989 base::TimeDelta::FromMilliseconds(2703))); | 965 base::TimeDelta::FromMilliseconds(2703))); |
| 990 } | 966 } |
| 991 | 967 |
| 992 // Verify that we output buffers before the entire cluster has been parsed. | 968 // Verify that we output buffers before the entire cluster has been parsed. |
| 993 TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) { | 969 TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) { |
| 994 ASSERT_TRUE(InitDemuxer(true, true, false)); | 970 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 995 | 971 |
| 996 ClusterBuilder cb; | 972 scoped_ptr<Cluster> cluster(GenerateCluster(0, 6)); |
| 997 cb.SetClusterTimecode(0); | |
| 998 AddSimpleBlock(&cb, kAudioTrackNum, 0, 10); | |
| 999 AddSimpleBlock(&cb, kVideoTrackNum, 1, 10); | |
| 1000 AddSimpleBlock(&cb, kVideoTrackNum, 2, 10); | |
| 1001 AddSimpleBlock(&cb, kAudioTrackNum, 3, 10); | |
| 1002 scoped_ptr<Cluster> cluster(cb.Finish()); | |
| 1003 | |
| 1004 scoped_refptr<DemuxerStream> audio = | 973 scoped_refptr<DemuxerStream> audio = |
| 1005 demuxer_->GetStream(DemuxerStream::AUDIO); | 974 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 1006 scoped_refptr<DemuxerStream> video = | 975 scoped_refptr<DemuxerStream> video = |
| 1007 demuxer_->GetStream(DemuxerStream::VIDEO); | 976 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 1008 | 977 |
| 1009 bool audio_read_done = false; | 978 bool audio_read_done = false; |
| 1010 bool video_read_done = false; | 979 bool video_read_done = false; |
| 1011 audio->Read(base::Bind(&OnReadDone, | 980 audio->Read(base::Bind(&OnReadDone, |
| 1012 base::TimeDelta::FromMilliseconds(0), | 981 base::TimeDelta::FromMilliseconds(0), |
| 1013 &audio_read_done)); | 982 &audio_read_done)); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1035 for (; i < cluster->size() && !video_read_done; ++i) { | 1004 for (; i < cluster->size() && !video_read_done; ++i) { |
| 1036 ASSERT_TRUE(AppendData(cluster->data() + i, 1)); | 1005 ASSERT_TRUE(AppendData(cluster->data() + i, 1)); |
| 1037 } | 1006 } |
| 1038 | 1007 |
| 1039 EXPECT_TRUE(video_read_done); | 1008 EXPECT_TRUE(video_read_done); |
| 1040 EXPECT_LT(i, cluster->size()); | 1009 EXPECT_LT(i, cluster->size()); |
| 1041 | 1010 |
| 1042 audio_read_done = false; | 1011 audio_read_done = false; |
| 1043 video_read_done = false; | 1012 video_read_done = false; |
| 1044 audio->Read(base::Bind(&OnReadDone, | 1013 audio->Read(base::Bind(&OnReadDone, |
| 1045 base::TimeDelta::FromMilliseconds(3), | 1014 base::TimeDelta::FromMilliseconds(23), |
| 1046 &audio_read_done)); | 1015 &audio_read_done)); |
| 1047 | 1016 |
| 1048 video->Read(base::Bind(&OnReadDone, | 1017 video->Read(base::Bind(&OnReadDone, |
| 1049 base::TimeDelta::FromMilliseconds(2), | 1018 base::TimeDelta::FromMilliseconds(34), |
| 1050 &video_read_done)); | 1019 &video_read_done)); |
| 1051 | 1020 |
| 1052 // Make sure the reads haven't completed yet. | 1021 // Make sure the reads haven't completed yet. |
| 1053 EXPECT_FALSE(audio_read_done); | 1022 EXPECT_FALSE(audio_read_done); |
| 1054 EXPECT_FALSE(video_read_done); | 1023 EXPECT_FALSE(video_read_done); |
| 1055 | 1024 |
| 1056 // Append the remaining data. | 1025 // Append the remaining data. |
| 1026 ASSERT_LT(i, cluster->size()); | |
| 1057 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); | 1027 ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i)); |
| 1058 | 1028 |
| 1059 EXPECT_TRUE(audio_read_done); | 1029 EXPECT_TRUE(audio_read_done); |
| 1060 EXPECT_TRUE(video_read_done); | 1030 EXPECT_TRUE(video_read_done); |
| 1061 } | 1031 } |
| 1062 | 1032 |
| 1063 | 1033 |
| 1064 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { | 1034 TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) { |
| 1065 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1035 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
| 1066 | 1036 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1098 | 1068 |
| 1099 std::vector<std::string> codecs(1); | 1069 std::vector<std::string> codecs(1); |
| 1100 codecs[0] = "vp8"; | 1070 codecs[0] = "vp8"; |
| 1101 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 1071 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
| 1102 ChunkDemuxer::kOk); | 1072 ChunkDemuxer::kOk); |
| 1103 | 1073 |
| 1104 ASSERT_TRUE(AppendInfoTracks(true, true, false)); | 1074 ASSERT_TRUE(AppendInfoTracks(true, true, false)); |
| 1105 } | 1075 } |
| 1106 | 1076 |
| 1107 } // namespace media | 1077 } // namespace media |
| OLD | NEW |