OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_filter_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" |
11 #include "media/filters/chunk_demuxer_client.h" | 11 #include "media/filters/chunk_demuxer_client.h" |
12 #include "media/webm/cluster_builder.h" | 12 #include "media/webm/cluster_builder.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 | 14 |
15 using ::testing::AnyNumber; | 15 using ::testing::AnyNumber; |
16 using ::testing::InSequence; | 16 using ::testing::InSequence; |
17 using ::testing::Return; | 17 using ::testing::Return; |
18 using ::testing::SetArgumentPointee; | 18 using ::testing::SetArgumentPointee; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 buf += audio_track_entry_size; | 107 buf += audio_track_entry_size; |
108 } | 108 } |
109 | 109 |
110 if (has_video) { | 110 if (has_video) { |
111 memcpy(buf, video_track_entry.get(), video_track_entry_size); | 111 memcpy(buf, video_track_entry.get(), video_track_entry_size); |
112 buf += video_track_entry_size; | 112 buf += video_track_entry_size; |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 void AppendData(const uint8* data, size_t length) { | 116 void AppendData(const uint8* data, size_t length) { |
117 EXPECT_CALL(mock_filter_host_, SetBufferedBytes(_)).Times(AnyNumber()); | 117 EXPECT_CALL(mock_demuxer_host_, SetBufferedBytes(_)).Times(AnyNumber()); |
118 EXPECT_CALL(mock_filter_host_, SetBufferedTime(_)).Times(AnyNumber()); | 118 EXPECT_CALL(mock_demuxer_host_, SetBufferedTime(_)).Times(AnyNumber()); |
119 EXPECT_CALL(mock_filter_host_, SetNetworkActivity(true)).Times(AnyNumber()); | 119 EXPECT_CALL(mock_demuxer_host_, SetNetworkActivity(true)) |
| 120 .Times(AnyNumber()); |
120 EXPECT_TRUE(demuxer_->AppendData(data, length)); | 121 EXPECT_TRUE(demuxer_->AppendData(data, length)); |
121 } | 122 } |
122 | 123 |
123 void AppendDataInPieces(const uint8* data, size_t length) { | 124 void AppendDataInPieces(const uint8* data, size_t length) { |
124 AppendDataInPieces(data, length, 7); | 125 AppendDataInPieces(data, length, 7); |
125 } | 126 } |
126 | 127 |
127 void AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { | 128 void AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { |
128 const uint8* start = data; | 129 const uint8* start = data; |
129 const uint8* end = data + length; | 130 const uint8* end = data + length; |
(...skipping 11 matching lines...) Expand all Loading... |
141 CreateInfoTracks(has_audio, has_video, &info_tracks, &info_tracks_size); | 142 CreateInfoTracks(has_audio, has_video, &info_tracks, &info_tracks_size); |
142 AppendData(info_tracks.get(), info_tracks_size); | 143 AppendData(info_tracks.get(), info_tracks_size); |
143 } | 144 } |
144 | 145 |
145 void InitDoneCalled(const base::TimeDelta& expected_duration, | 146 void InitDoneCalled(const base::TimeDelta& expected_duration, |
146 PipelineStatus expected_status, | 147 PipelineStatus expected_status, |
147 PipelineStatus status) { | 148 PipelineStatus status) { |
148 EXPECT_EQ(status, expected_status); | 149 EXPECT_EQ(status, expected_status); |
149 | 150 |
150 if (status == PIPELINE_OK) { | 151 if (status == PIPELINE_OK) { |
151 EXPECT_CALL(mock_filter_host_, SetDuration(expected_duration)); | 152 EXPECT_CALL(mock_demuxer_host_, SetDuration(expected_duration)); |
152 EXPECT_CALL(mock_filter_host_, SetCurrentReadPosition(_)); | 153 EXPECT_CALL(mock_demuxer_host_, SetCurrentReadPosition(_)); |
153 | 154 |
154 demuxer_->set_host(&mock_filter_host_); | 155 demuxer_->set_host(&mock_demuxer_host_); |
155 } | 156 } |
156 } | 157 } |
157 | 158 |
158 PipelineStatusCB CreateInitDoneCB(int duration, | 159 PipelineStatusCB CreateInitDoneCB(int duration, |
159 PipelineStatus expected_status) { | 160 PipelineStatus expected_status) { |
160 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 161 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, |
161 base::Unretained(this), | 162 base::Unretained(this), |
162 base::TimeDelta::FromMilliseconds(duration), | 163 base::TimeDelta::FromMilliseconds(duration), |
163 expected_status); | 164 expected_status); |
164 } | 165 } |
(...skipping 21 matching lines...) Expand all Loading... |
186 } | 187 } |
187 | 188 |
188 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode, | 189 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode, |
189 int size) { | 190 int size) { |
190 scoped_array<uint8> data(new uint8[size]); | 191 scoped_array<uint8> data(new uint8[size]); |
191 cb->AddSimpleBlock(track_num, timecode, 0, data.get(), size); | 192 cb->AddSimpleBlock(track_num, timecode, 0, data.get(), size); |
192 } | 193 } |
193 | 194 |
194 MOCK_METHOD1(Checkpoint, void(int id)); | 195 MOCK_METHOD1(Checkpoint, void(int id)); |
195 | 196 |
196 MockFilterHost mock_filter_host_; | 197 MockDemuxerHost mock_demuxer_host_; |
197 | 198 |
198 scoped_ptr<MockChunkDemuxerClient> client_; | 199 scoped_ptr<MockChunkDemuxerClient> client_; |
199 scoped_refptr<ChunkDemuxer> demuxer_; | 200 scoped_refptr<ChunkDemuxer> demuxer_; |
200 | 201 |
201 private: | 202 private: |
202 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 203 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
203 }; | 204 }; |
204 | 205 |
205 TEST_F(ChunkDemuxerTest, TestInit) { | 206 TEST_F(ChunkDemuxerTest, TestInit) { |
206 // Test no streams, audio-only, video-only, and audio & video scenarios. | 207 // Test no streams, audio-only, video-only, and audio & video scenarios. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 // that overlaps. | 342 // that overlaps. |
342 cb.SetClusterTimecode(5); | 343 cb.SetClusterTimecode(5); |
343 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 344 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
344 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 345 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
345 AddSimpleBlock(&cb, kAudioTrackNum, 28); | 346 AddSimpleBlock(&cb, kAudioTrackNum, 28); |
346 AddSimpleBlock(&cb, kVideoTrackNum, 40); | 347 AddSimpleBlock(&cb, kVideoTrackNum, 40); |
347 scoped_ptr<Cluster> clusterB(cb.Finish()); | 348 scoped_ptr<Cluster> clusterB(cb.Finish()); |
348 | 349 |
349 // Make sure that AppendData() fails because this cluster data | 350 // Make sure that AppendData() fails because this cluster data |
350 // is before previous data. | 351 // is before previous data. |
351 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 352 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
352 AppendData(clusterB->data(), clusterB->size()); | 353 AppendData(clusterB->data(), clusterB->size()); |
353 | 354 |
354 // Verify that AppendData() doesn't accept more data now. | 355 // Verify that AppendData() doesn't accept more data now. |
355 cb.SetClusterTimecode(45); | 356 cb.SetClusterTimecode(45); |
356 AddSimpleBlock(&cb, kAudioTrackNum, 45); | 357 AddSimpleBlock(&cb, kAudioTrackNum, 45); |
357 AddSimpleBlock(&cb, kVideoTrackNum, 45); | 358 AddSimpleBlock(&cb, kVideoTrackNum, 45); |
358 scoped_ptr<Cluster> clusterC(cb.Finish()); | 359 scoped_ptr<Cluster> clusterC(cb.Finish()); |
359 EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); | 360 EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
360 } | 361 } |
361 | 362 |
362 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { | 363 TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { |
363 InitDemuxer(true, true); | 364 InitDemuxer(true, true); |
364 | 365 |
365 ClusterBuilder cb; | 366 ClusterBuilder cb; |
366 | 367 |
367 // Test the case where block timecodes are not monotonically | 368 // Test the case where block timecodes are not monotonically |
368 // increasing but stay above the cluster timecode. | 369 // increasing but stay above the cluster timecode. |
369 cb.SetClusterTimecode(5); | 370 cb.SetClusterTimecode(5); |
370 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 371 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
371 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 372 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
372 AddSimpleBlock(&cb, kAudioTrackNum, 7); | 373 AddSimpleBlock(&cb, kAudioTrackNum, 7); |
373 AddSimpleBlock(&cb, kVideoTrackNum, 15); | 374 AddSimpleBlock(&cb, kVideoTrackNum, 15); |
374 scoped_ptr<Cluster> clusterA(cb.Finish()); | 375 scoped_ptr<Cluster> clusterA(cb.Finish()); |
375 | 376 |
376 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 377 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
377 AppendData(clusterA->data(), clusterA->size()); | 378 AppendData(clusterA->data(), clusterA->size()); |
378 | 379 |
379 // Verify that AppendData() doesn't accept more data now. | 380 // Verify that AppendData() doesn't accept more data now. |
380 cb.SetClusterTimecode(20); | 381 cb.SetClusterTimecode(20); |
381 AddSimpleBlock(&cb, kAudioTrackNum, 20); | 382 AddSimpleBlock(&cb, kAudioTrackNum, 20); |
382 AddSimpleBlock(&cb, kVideoTrackNum, 20); | 383 AddSimpleBlock(&cb, kVideoTrackNum, 20); |
383 scoped_ptr<Cluster> clusterB(cb.Finish()); | 384 scoped_ptr<Cluster> clusterB(cb.Finish()); |
384 EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); | 385 EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
385 } | 386 } |
386 | 387 |
387 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { | 388 TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { |
388 InitDemuxer(true, true); | 389 InitDemuxer(true, true); |
389 | 390 |
390 ClusterBuilder cb; | 391 ClusterBuilder cb; |
391 | 392 |
392 // Test timecodes going backwards and including values less than the cluster | 393 // Test timecodes going backwards and including values less than the cluster |
393 // timecode. | 394 // timecode. |
394 cb.SetClusterTimecode(5); | 395 cb.SetClusterTimecode(5); |
395 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 396 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
396 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 397 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
397 AddSimpleBlock(&cb, kAudioTrackNum, 3); | 398 AddSimpleBlock(&cb, kAudioTrackNum, 3); |
398 AddSimpleBlock(&cb, kVideoTrackNum, 3); | 399 AddSimpleBlock(&cb, kVideoTrackNum, 3); |
399 scoped_ptr<Cluster> clusterA(cb.Finish()); | 400 scoped_ptr<Cluster> clusterA(cb.Finish()); |
400 | 401 |
401 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 402 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
402 AppendData(clusterA->data(), clusterA->size()); | 403 AppendData(clusterA->data(), clusterA->size()); |
403 | 404 |
404 // Verify that AppendData() doesn't accept more data now. | 405 // Verify that AppendData() doesn't accept more data now. |
405 cb.SetClusterTimecode(6); | 406 cb.SetClusterTimecode(6); |
406 AddSimpleBlock(&cb, kAudioTrackNum, 6); | 407 AddSimpleBlock(&cb, kAudioTrackNum, 6); |
407 AddSimpleBlock(&cb, kVideoTrackNum, 6); | 408 AddSimpleBlock(&cb, kVideoTrackNum, 6); |
408 scoped_ptr<Cluster> clusterB(cb.Finish()); | 409 scoped_ptr<Cluster> clusterB(cb.Finish()); |
409 EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); | 410 EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
410 } | 411 } |
411 | 412 |
412 | 413 |
413 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { | 414 TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { |
414 InitDemuxer(true, true); | 415 InitDemuxer(true, true); |
415 | 416 |
416 ClusterBuilder cb; | 417 ClusterBuilder cb; |
417 | 418 |
418 // Test strict monotonic increasing timestamps on a per stream | 419 // Test strict monotonic increasing timestamps on a per stream |
419 // basis. | 420 // basis. |
420 cb.SetClusterTimecode(5); | 421 cb.SetClusterTimecode(5); |
421 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 422 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
422 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 423 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
423 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 424 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
424 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 425 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
425 scoped_ptr<Cluster> cluster(cb.Finish()); | 426 scoped_ptr<Cluster> cluster(cb.Finish()); |
426 | 427 |
427 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 428 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
428 AppendData(cluster->data(), cluster->size()); | 429 AppendData(cluster->data(), cluster->size()); |
429 } | 430 } |
430 | 431 |
431 TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { | 432 TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { |
432 InitDemuxer(true, true); | 433 InitDemuxer(true, true); |
433 | 434 |
434 ClusterBuilder cb; | 435 ClusterBuilder cb; |
435 | 436 |
436 // Test strict monotonic increasing timestamps on a per stream | 437 // Test strict monotonic increasing timestamps on a per stream |
437 // basis across clusters. | 438 // basis across clusters. |
438 cb.SetClusterTimecode(5); | 439 cb.SetClusterTimecode(5); |
439 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 440 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
440 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 441 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
441 scoped_ptr<Cluster> clusterA(cb.Finish()); | 442 scoped_ptr<Cluster> clusterA(cb.Finish()); |
442 | 443 |
443 AppendData(clusterA->data(), clusterA->size()); | 444 AppendData(clusterA->data(), clusterA->size()); |
444 | 445 |
445 cb.SetClusterTimecode(5); | 446 cb.SetClusterTimecode(5); |
446 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 447 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
447 AddSimpleBlock(&cb, kVideoTrackNum, 7); | 448 AddSimpleBlock(&cb, kVideoTrackNum, 7); |
448 scoped_ptr<Cluster> clusterB(cb.Finish()); | 449 scoped_ptr<Cluster> clusterB(cb.Finish()); |
449 | 450 |
450 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 451 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
451 AppendData(clusterB->data(), clusterB->size()); | 452 AppendData(clusterB->data(), clusterB->size()); |
452 | 453 |
453 // Verify that AppendData() doesn't accept more data now. | 454 // Verify that AppendData() doesn't accept more data now. |
454 cb.SetClusterTimecode(10); | 455 cb.SetClusterTimecode(10); |
455 AddSimpleBlock(&cb, kAudioTrackNum, 10); | 456 AddSimpleBlock(&cb, kAudioTrackNum, 10); |
456 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 457 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
457 scoped_ptr<Cluster> clusterC(cb.Finish()); | 458 scoped_ptr<Cluster> clusterC(cb.Finish()); |
458 EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); | 459 EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
459 } | 460 } |
460 | 461 |
(...skipping 23 matching lines...) Expand all Loading... |
484 | 485 |
485 ClusterBuilder cb; | 486 ClusterBuilder cb; |
486 cb.SetClusterTimecode(0); | 487 cb.SetClusterTimecode(0); |
487 AddSimpleBlock(&cb, kAudioTrackNum, 0); | 488 AddSimpleBlock(&cb, kAudioTrackNum, 0); |
488 AddSimpleBlock(&cb, kVideoTrackNum, 0); | 489 AddSimpleBlock(&cb, kVideoTrackNum, 0); |
489 AddSimpleBlock(&cb, kAudioTrackNum, 23); | 490 AddSimpleBlock(&cb, kAudioTrackNum, 23); |
490 AddSimpleBlock(&cb, kVideoTrackNum, 33); | 491 AddSimpleBlock(&cb, kVideoTrackNum, 33); |
491 scoped_ptr<Cluster> cluster(cb.Finish()); | 492 scoped_ptr<Cluster> cluster(cb.Finish()); |
492 AppendData(cluster->data(), cluster->size()); | 493 AppendData(cluster->data(), cluster->size()); |
493 | 494 |
494 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); | 495 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
495 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); | 496 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); |
496 } | 497 } |
497 | 498 |
498 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { | 499 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { |
499 InitDemuxer(true, true); | 500 InitDemuxer(true, true); |
500 | 501 |
501 ClusterBuilder cb; | 502 ClusterBuilder cb; |
502 cb.SetClusterTimecode(0); | 503 cb.SetClusterTimecode(0); |
503 AddSimpleBlock(&cb, kAudioTrackNum, 0); | 504 AddSimpleBlock(&cb, kAudioTrackNum, 0); |
504 AddSimpleBlock(&cb, kVideoTrackNum, 0); | 505 AddSimpleBlock(&cb, kVideoTrackNum, 0); |
505 AddSimpleBlock(&cb, kAudioTrackNum, 23); | 506 AddSimpleBlock(&cb, kAudioTrackNum, 23); |
506 AddSimpleBlock(&cb, kVideoTrackNum, 33); | 507 AddSimpleBlock(&cb, kVideoTrackNum, 33); |
507 scoped_ptr<Cluster> cluster(cb.Finish()); | 508 scoped_ptr<Cluster> cluster(cb.Finish()); |
508 AppendData(cluster->data(), cluster->size()); | 509 AppendData(cluster->data(), cluster->size()); |
509 | 510 |
510 EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK)); | 511 EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); |
511 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); | 512 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
512 } | 513 } |
513 | 514 |
514 // Helper class to reduce duplicate code when testing end of stream | 515 // Helper class to reduce duplicate code when testing end of stream |
515 // Read() behavior. | 516 // Read() behavior. |
516 class EndOfStreamHelper { | 517 class EndOfStreamHelper { |
517 public: | 518 public: |
518 EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) | 519 EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) |
519 : demuxer_(demuxer), | 520 : demuxer_(demuxer), |
520 audio_read_done_(false), | 521 audio_read_done_(false), |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 base::TimeDelta::FromMilliseconds( | 772 base::TimeDelta::FromMilliseconds( |
772 buffer_timestamps[i].video_time), | 773 buffer_timestamps[i].video_time), |
773 &video_read_done)); | 774 &video_read_done)); |
774 | 775 |
775 EXPECT_TRUE(audio_read_done); | 776 EXPECT_TRUE(audio_read_done); |
776 EXPECT_TRUE(video_read_done); | 777 EXPECT_TRUE(video_read_done); |
777 } | 778 } |
778 } | 779 } |
779 | 780 |
780 } // namespace media | 781 } // namespace media |
OLD | NEW |