OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <string> | 5 #include <string> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/callback_helpers.h" | |
8 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
9 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
10 #include "media/base/android/media_codec_bridge.h" | 11 #include "media/base/android/media_codec_bridge.h" |
11 #include "media/base/android/media_drm_bridge.h" | 12 #include "media/base/android/media_drm_bridge.h" |
12 #include "media/base/android/media_player_manager.h" | 13 #include "media/base/android/media_player_manager.h" |
13 #include "media/base/android/media_source_player.h" | 14 #include "media/base/android/media_source_player.h" |
15 #include "media/base/bind_to_loop.h" | |
14 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
15 #include "media/base/test_data_util.h" | 17 #include "media/base/test_data_util.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "ui/gl/android/surface_texture.h" | 19 #include "ui/gl/android/surface_texture.h" |
18 | 20 |
19 namespace media { | 21 namespace media { |
20 | 22 |
21 // Helper macro to skip the test if MediaCodecBridge isn't available. | 23 // Helper macro to skip the test if MediaCodecBridge isn't available. |
22 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \ | 24 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \ |
23 do { \ | 25 do { \ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 virtual void OnKeyAdded(int key_id, | 75 virtual void OnKeyAdded(int key_id, |
74 const std::string& session_id) OVERRIDE {} | 76 const std::string& session_id) OVERRIDE {} |
75 virtual void OnKeyError(int key_id, | 77 virtual void OnKeyError(int key_id, |
76 const std::string& session_id, | 78 const std::string& session_id, |
77 MediaKeys::KeyError error_code, | 79 MediaKeys::KeyError error_code, |
78 int system_code) OVERRIDE {} | 80 int system_code) OVERRIDE {} |
79 virtual void OnKeyMessage(int key_id, | 81 virtual void OnKeyMessage(int key_id, |
80 const std::string& session_id, | 82 const std::string& session_id, |
81 const std::vector<uint8>& message, | 83 const std::vector<uint8>& message, |
82 const std::string& destination_url) OVERRIDE {} | 84 const std::string& destination_url) OVERRIDE {} |
85 virtual void OnMediaDecoderCallbackForTesting() OVERRIDE { | |
acolwell GONE FROM CHROMIUM
2013/10/30 23:29:53
This should be in MSP not here.
wolenetz
2013/10/31 01:39:11
Done.
| |
86 if (media_decoder_test_cb_.is_null()) | |
87 return; | |
88 base::ResetAndReturn(&media_decoder_test_cb_).Run(); | |
89 } | |
90 | |
91 // Hook the next OnMediaDecoderCallbackForTesting() to run |decode_cb|. | |
92 void HookNextMediaDecoderCallback(const base::Closure& decode_cb) { | |
93 media_decoder_test_cb_ = decode_cb; | |
94 } | |
83 | 95 |
84 private: | 96 private: |
85 base::MessageLoop* message_loop_; | 97 base::MessageLoop* message_loop_; |
98 base::Closure media_decoder_test_cb_; | |
86 | 99 |
87 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); | 100 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); |
88 }; | 101 }; |
89 | 102 |
90 class MockDemuxerAndroid : public DemuxerAndroid { | 103 class MockDemuxerAndroid : public DemuxerAndroid { |
91 public: | 104 public: |
92 explicit MockDemuxerAndroid(base::MessageLoop* message_loop) | 105 explicit MockDemuxerAndroid(base::MessageLoop* message_loop) |
93 : message_loop_(message_loop), | 106 : message_loop_(message_loop), |
94 num_data_requests_(0), | 107 num_data_requests_(0), |
95 num_seek_requests_(0), | 108 num_seek_requests_(0), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 | 148 |
136 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); | 149 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); |
137 }; | 150 }; |
138 | 151 |
139 class MediaSourcePlayerTest : public testing::Test { | 152 class MediaSourcePlayerTest : public testing::Test { |
140 public: | 153 public: |
141 MediaSourcePlayerTest() | 154 MediaSourcePlayerTest() |
142 : manager_(&message_loop_), | 155 : manager_(&message_loop_), |
143 demuxer_(new MockDemuxerAndroid(&message_loop_)), | 156 demuxer_(new MockDemuxerAndroid(&message_loop_)), |
144 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)), | 157 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)), |
158 decoder_callback_hook_executed_(false), | |
145 surface_texture_a_is_next_(true) {} | 159 surface_texture_a_is_next_(true) {} |
146 virtual ~MediaSourcePlayerTest() {} | 160 virtual ~MediaSourcePlayerTest() {} |
147 | 161 |
148 protected: | 162 protected: |
149 // Get the decoder job from the MediaSourcePlayer. | 163 // Get the decoder job from the MediaSourcePlayer. |
150 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) { | 164 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) { |
151 if (is_audio) { | 165 if (is_audio) { |
152 return reinterpret_cast<MediaDecoderJob*>( | 166 return reinterpret_cast<MediaDecoderJob*>( |
153 player_.audio_decoder_job_.get()); | 167 player_.audio_decoder_job_.get()); |
154 } | 168 } |
155 return reinterpret_cast<MediaDecoderJob*>( | 169 return reinterpret_cast<MediaDecoderJob*>( |
156 player_.video_decoder_job_.get()); | 170 player_.video_decoder_job_.get()); |
157 } | 171 } |
158 | 172 |
159 // Get the per-job prerolling status from the MediaSourcePlayer's job matching | 173 // Get the per-job prerolling status from the MediaSourcePlayer's job matching |
160 // |is_audio|. Caller must guard against NPE if the player's job is NULL. | 174 // |is_audio|. Caller must guard against NPE if the player's job is NULL. |
161 bool IsPrerolling(bool is_audio) { | 175 bool IsPrerolling(bool is_audio) { |
162 return GetMediaDecoderJob(is_audio)->prerolling(); | 176 return GetMediaDecoderJob(is_audio)->prerolling(); |
163 } | 177 } |
164 | 178 |
165 // Get the preroll timestamp from the MediaSourcePlayer. | 179 // Get the preroll timestamp from the MediaSourcePlayer. |
166 base::TimeDelta GetPrerollTimestamp() { | 180 base::TimeDelta GetPrerollTimestamp() { |
167 return player_.preroll_timestamp_; | 181 return player_.preroll_timestamp_; |
168 } | 182 } |
169 | 183 |
184 // Check if the player is pending a prefetch done event. | |
185 bool IsPendingPrefetchDone() { | |
186 return player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING); | |
187 } | |
188 | |
189 // Check if the player is pending a config change event. | |
190 bool IsPendingConfigChange() { | |
191 return player_.IsEventPending(player_.CONFIG_CHANGE_EVENT_PENDING); | |
192 } | |
193 | |
194 // Check if the player is pending a seek event. | |
195 bool IsPendingSeek() { | |
196 return player_.IsEventPending(player_.SEEK_EVENT_PENDING); | |
197 } | |
198 | |
199 // Check if the player is pending a surface change event. | |
200 bool IsPendingSurfaceChange() { | |
201 return player_.IsEventPending(player_.SURFACE_CHANGE_EVENT_PENDING); | |
202 } | |
203 | |
204 // Check if the player is pending a prefetch request event. | |
205 bool IsPendingPrefetchRequest() { | |
206 return player_.IsEventPending(player_.PREFETCH_REQUEST_EVENT_PENDING); | |
207 } | |
208 | |
209 // Simulate player has reached starvation timeout. | |
210 void TriggerPlayerStarvation() { | |
211 player_.decoder_starvation_callback_.Cancel(); | |
212 player_.OnDecoderStarved(); | |
213 } | |
214 | |
215 // Asynch test callback posted upon decode completion to verify that a pending | |
216 // prefetch done event is cleared across |player_|'s Release(). This helps | |
217 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met. | |
218 void ReleaseWithPendingPrefetchDoneVerification() { | |
219 EXPECT_TRUE(player_.IsPlaying()); | |
220 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
221 EXPECT_TRUE(IsPendingPrefetchDone()); | |
222 player_.Release(); | |
223 EXPECT_FALSE(IsPendingPrefetchDone()); | |
224 EXPECT_FALSE(player_.IsPlaying()); | |
225 EXPECT_FALSE(decoder_callback_hook_executed_); | |
226 decoder_callback_hook_executed_ = true; | |
227 } | |
228 | |
170 DemuxerConfigs CreateAudioDemuxerConfigs() { | 229 DemuxerConfigs CreateAudioDemuxerConfigs() { |
171 DemuxerConfigs configs; | 230 DemuxerConfigs configs; |
172 configs.audio_codec = kCodecVorbis; | 231 configs.audio_codec = kCodecVorbis; |
173 configs.audio_channels = 2; | 232 configs.audio_channels = 2; |
174 configs.audio_sampling_rate = 44100; | 233 configs.audio_sampling_rate = 44100; |
175 configs.is_audio_encrypted = false; | 234 configs.is_audio_encrypted = false; |
176 configs.duration_ms = kDefaultDurationInMs; | 235 configs.duration_ms = kDefaultDurationInMs; |
177 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata"); | 236 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata"); |
178 configs.audio_extra_data = std::vector<uint8>( | 237 configs.audio_extra_data = std::vector<uint8>( |
179 buffer->data(), | 238 buffer->data(), |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 } | 520 } |
462 | 521 |
463 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, | 522 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, |
464 const std::string& security_level, | 523 const std::string& security_level, |
465 const std::string& container, | 524 const std::string& container, |
466 const std::vector<std::string>& codecs) { | 525 const std::vector<std::string>& codecs) { |
467 return MediaSourcePlayer::IsTypeSupported( | 526 return MediaSourcePlayer::IsTypeSupported( |
468 scheme_uuid, security_level, container, codecs); | 527 scheme_uuid, security_level, container, codecs); |
469 } | 528 } |
470 | 529 |
471 protected: | |
472 base::MessageLoop message_loop_; | 530 base::MessageLoop message_loop_; |
473 MockMediaPlayerManager manager_; | 531 MockMediaPlayerManager manager_; |
474 MockDemuxerAndroid* demuxer_; // Owned by |player_|. | 532 MockDemuxerAndroid* demuxer_; // Owned by |player_|. |
475 MediaSourcePlayer player_; | 533 MediaSourcePlayer player_; |
476 | 534 |
535 // Track whether a possibly asynch decoder callback test hook has run. | |
536 bool decoder_callback_hook_executed_; | |
537 | |
477 // We need to keep the surface texture while the decoder is actively decoding. | 538 // We need to keep the surface texture while the decoder is actively decoding. |
478 // Otherwise, it may trigger unexpected crashes on some devices. To switch | 539 // Otherwise, it may trigger unexpected crashes on some devices. To switch |
479 // surfaces, tests need to create a new surface texture without releasing | 540 // surfaces, tests need to create a new surface texture without releasing |
480 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle | 541 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle |
481 // between two surface textures, only replacing the N-2 texture. Assumption is | 542 // between two surface textures, only replacing the N-2 texture. Assumption is |
482 // that no more than N-1 texture is in use by decoder when | 543 // that no more than N-1 texture is in use by decoder when |
483 // CreateNextTextureAndSetVideoSurface() is called. | 544 // CreateNextTextureAndSetVideoSurface() is called. |
484 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_; | 545 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_; |
485 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_; | 546 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_; |
486 bool surface_texture_a_is_next_; | 547 bool surface_texture_a_is_next_; |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1372 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs()); | 1433 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs()); |
1373 MediaDecoderJob* second_job = GetMediaDecoderJob(false); | 1434 MediaDecoderJob* second_job = GetMediaDecoderJob(false); |
1374 EXPECT_NE(first_job, second_job); | 1435 EXPECT_NE(first_job, second_job); |
1375 EXPECT_TRUE(second_job); | 1436 EXPECT_TRUE(second_job); |
1376 | 1437 |
1377 EXPECT_EQ(3, demuxer_->num_data_requests()); | 1438 EXPECT_EQ(3, demuxer_->num_data_requests()); |
1378 EXPECT_EQ(1, demuxer_->num_config_requests()); | 1439 EXPECT_EQ(1, demuxer_->num_config_requests()); |
1379 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1440 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
1380 } | 1441 } |
1381 | 1442 |
1443 TEST_F(MediaSourcePlayerTest, ReleaseClearsSurfaceChangeAndPrefetchDone) { | |
1444 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1445 | |
1446 // Test that Release() clears both a pending surface change event as well | |
1447 // as a pending prefetch done event. | |
1448 StartVideoDecoderJob(); | |
1449 CreateNextTextureAndSetVideoSurface(); | |
1450 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1451 EXPECT_TRUE(GetMediaDecoderJob(false)); | |
1452 | |
1453 EXPECT_FALSE(IsPendingSurfaceChange()); | |
1454 CreateNextTextureAndSetVideoSurface(); | |
1455 EXPECT_TRUE(IsPendingSurfaceChange()); | |
1456 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1457 | |
1458 player_.Release(); | |
1459 EXPECT_FALSE(IsPendingSurfaceChange()); | |
1460 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1461 | |
1462 // Player should have no decoder job until after Start() and setting non-empty | |
1463 // surface. | |
1464 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
1465 EXPECT_FALSE(player_.IsPlaying()); | |
1466 StartVideoDecoderJob(); | |
1467 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
1468 CreateNextTextureAndSetVideoSurface(); | |
1469 EXPECT_TRUE(GetMediaDecoderJob(false)); | |
1470 } | |
1471 | |
1472 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) { | |
1473 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1474 | |
1475 // Test that if OnPrefetchDone() had already been posted before and is | |
1476 // executed after Release(), player does not DCHECK. | |
1477 StartAudioDecoderJob(); | |
1478 | |
1479 // Escape the original prefetch by decoding a single access unit. | |
1480 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
1481 message_loop_.Run(); | |
1482 | |
1483 // Prime the job with a few more access units, so that a later prefetch, | |
1484 // triggered by starvation to simulate decoder underrun, can trivially | |
1485 // post task to run OnPrefetchDone(). | |
1486 player_.OnDemuxerDataAvailable( | |
1487 CreateReadFromDemuxerAckWithConfigChanged(true, 4)); | |
1488 | |
1489 EXPECT_TRUE(GetMediaDecoderJob(true) && | |
1490 GetMediaDecoderJob(true)->is_decoding()); | |
1491 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
1492 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1493 | |
1494 // Simulate decoder underrun, so trivial prefetch starts while still decoding. | |
1495 // The prefetch and posting of OnPrefetchDone() will not occur until next | |
1496 // MediaDecoderCallBack() occurs. | |
1497 TriggerPlayerStarvation(); | |
1498 EXPECT_TRUE(IsPendingPrefetchRequest()); | |
1499 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1500 | |
1501 // Upon the next successful decode callback, post a task to Release() | |
1502 // |player_|, such that the trivial OnPrefetchDone() task posting also occurs | |
1503 // and should execute after the Release(). | |
1504 manager_.HookNextMediaDecoderCallback(media::BindToLoop( | |
1505 message_loop_.message_loop_proxy(), | |
1506 base::Bind( | |
1507 &MediaSourcePlayerTest_ReleaseWithOnPrefetchDoneAlreadyPosted_Test:: | |
1508 ReleaseWithPendingPrefetchDoneVerification, | |
1509 base::Unretained(this)))); | |
1510 | |
1511 while (GetMediaDecoderJob(true)) | |
1512 message_loop_.RunUntilIdle(); | |
1513 EXPECT_TRUE(decoder_callback_hook_executed_); | |
1514 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
1515 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1516 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1517 EXPECT_FALSE(player_.IsPlaying()); | |
1518 | |
1519 // Player should have no decoder job until after Start(). | |
1520 StartAudioDecoderJob(); | |
1521 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1522 } | |
1523 | |
1524 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) { | |
1525 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1526 | |
1527 // Test that if Release() occurs after SeekTo(), but the DemuxerSeek IPC | |
1528 // request has not yet been sent, that the seek request will be sent after | |
1529 // Release(). Also, if OnDemuxerSeekDone() occurs prior to next Start(), then | |
1530 // the player will resume correct post-seek preroll upon Start(). | |
1531 StartAudioDecoderJob(); | |
1532 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1533 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding()); | |
1534 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
1535 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
1536 | |
1537 // SeekTo() while the job is decoding, so DemuxerSeek IPC transmission pends | |
1538 // decoder completion (or player Release()). | |
1539 player_.SeekTo(base::TimeDelta::FromMilliseconds(100)); | |
1540 EXPECT_TRUE(IsPendingSeek()); | |
1541 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF()); | |
1542 EXPECT_EQ(0, demuxer_->num_seek_requests()); | |
1543 | |
1544 // TODO(qinmin/wolenetz): Don't drop previously received data. See | |
1545 // http://crbug.com/306314 and http://crbug.com/304234. | |
1546 player_.Release(); | |
1547 EXPECT_FALSE(player_.IsPlaying()); | |
1548 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1549 EXPECT_TRUE(IsPendingSeek()); | |
1550 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1551 | |
1552 player_.OnDemuxerSeekDone(kNoTimestamp()); | |
1553 EXPECT_FALSE(IsPendingSeek()); | |
1554 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); | |
1555 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1556 EXPECT_FALSE(player_.IsPlaying()); | |
1557 | |
1558 // Player should begin prefetch and resume preroll upon Start(). | |
1559 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1560 StartAudioDecoderJob(); | |
1561 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1562 EXPECT_FALSE(IsPendingSeek()); | |
1563 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1564 EXPECT_TRUE(IsPrerolling(true)); | |
1565 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); | |
1566 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1567 | |
1568 // No further seek should have been requested since Release(), above. | |
1569 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1570 } | |
1571 | |
1572 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) { | |
1573 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1574 | |
1575 // Test that if Release() occurs after SeekTo(), but the DemuxerSeek IPC | |
1576 // request has not yet been sent, that the seek request will be sent after | |
1577 // Release(). Also, if OnDemuxerSeekDone() does not occur until after the next | |
1578 // Start(), then the player remains pending seek done and, after | |
1579 // OnDemuxerSeekDone(), resumes correct post-seek preroll. | |
1580 StartAudioDecoderJob(); | |
1581 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1582 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding()); | |
1583 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
1584 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
1585 | |
1586 // SeekTo() while the job is decoding, so DemuxerSeek IPC transmission pends | |
1587 // decoder completion (or player Release()). | |
1588 player_.SeekTo(base::TimeDelta::FromMilliseconds(100)); | |
1589 EXPECT_TRUE(IsPendingSeek()); | |
1590 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF()); | |
1591 EXPECT_EQ(0, demuxer_->num_seek_requests()); | |
1592 | |
1593 // TODO(qinmin/wolenetz): Don't drop previously received data. See | |
1594 // http://crbug.com/306314 and http://crbug.com/304234. | |
1595 player_.Release(); | |
1596 EXPECT_FALSE(player_.IsPlaying()); | |
1597 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1598 EXPECT_TRUE(IsPendingSeek()); | |
1599 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1600 | |
1601 // Player should not prefetch upon Start() nor create the decoder job, due to | |
1602 // awaiting DemuxerSeekDone. | |
1603 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1604 StartAudioDecoderJob(); | |
1605 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1606 EXPECT_TRUE(IsPendingSeek()); | |
1607 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
1608 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1609 | |
1610 player_.OnDemuxerSeekDone(kNoTimestamp()); | |
1611 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1612 EXPECT_FALSE(IsPendingSeek()); | |
1613 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1614 EXPECT_TRUE(IsPrerolling(true)); | |
1615 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); | |
1616 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1617 | |
1618 // No further seek should have been requested since Release(), above. | |
1619 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1620 } | |
1621 | |
1622 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) { | |
1623 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1624 | |
1625 // Test that if Release() occurs after |kConfigChanged| detected and new | |
1626 // configs requested of demuxer, and the requested configs arrive before | |
1627 // the next Start(), then the player completes the pending config change | |
1628 // processing on their receipt. | |
1629 StartConfigChange(true, true, 0); | |
1630 | |
1631 player_.Release(); | |
1632 EXPECT_FALSE(player_.IsPlaying()); | |
1633 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1634 EXPECT_TRUE(IsPendingConfigChange()); | |
1635 | |
1636 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs()); | |
1637 EXPECT_FALSE(IsPendingConfigChange()); | |
1638 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1639 EXPECT_FALSE(player_.IsPlaying()); | |
1640 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1641 | |
1642 // Player should resume upon Start(), even without further configs supplied. | |
1643 player_.Start(); | |
1644 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1645 EXPECT_FALSE(IsPendingConfigChange()); | |
1646 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1647 EXPECT_TRUE(player_.IsPlaying()); | |
1648 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1649 | |
1650 // No further config request should have occurred since StartConfigChange(). | |
1651 EXPECT_EQ(1, demuxer_->num_config_requests()); | |
1652 } | |
1653 | |
1654 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) { | |
1655 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1656 | |
1657 // Test that if Release() occurs after |kConfigChanged| detected and new | |
1658 // configs requested of demuxer, and the requested configs arrive after the | |
1659 // next Start(), then the player pends job creation until the new configs | |
1660 // arrive. | |
1661 StartConfigChange(true, true, 0); | |
1662 | |
1663 player_.Release(); | |
1664 EXPECT_FALSE(player_.IsPlaying()); | |
1665 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1666 EXPECT_TRUE(IsPendingConfigChange()); | |
1667 | |
1668 player_.Start(); | |
1669 EXPECT_TRUE(player_.IsPlaying()); | |
1670 EXPECT_FALSE(GetMediaDecoderJob(true)); | |
1671 EXPECT_TRUE(IsPendingConfigChange()); | |
1672 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1673 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1674 | |
1675 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs()); | |
1676 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
1677 EXPECT_FALSE(IsPendingConfigChange()); | |
1678 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1679 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1680 | |
1681 // No further config request should have occurred since StartConfigChange(). | |
1682 EXPECT_EQ(1, demuxer_->num_config_requests()); | |
1683 } | |
1684 | |
1685 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) { | |
1686 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1687 | |
1688 // Test that if Release() occurs after a browser seek's DemuxerSeek IPC | |
1689 // request has been sent, that the seek survives the Release(). Also, if | |
1690 // OnDemuxerSeekDone() occurs prior to the next Start(), then the player will | |
1691 // resume correct post-seek preroll upon Start(). | |
1692 // Note, the SeekToThenReleaseThenDemuxerSeek* tests, above, cover the | |
1693 // case where seek request has not yet been sent at time of Release(). Browser | |
1694 // seeks use similar logic, so no extra test coverage is deemed necessary. On | |
1695 // removal of browser seeks, consider retaining a regular seek version of this | |
1696 // test. | |
1697 | |
1698 BrowserSeekPlayer(false); | |
1699 EXPECT_FALSE(GetMediaDecoderJob(false)); // It is reset pending the seek. | |
1700 EXPECT_TRUE(IsPendingSeek()); | |
1701 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime(); | |
1702 | |
1703 player_.Release(); | |
1704 EXPECT_FALSE(player_.IsPlaying()); | |
1705 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
1706 EXPECT_TRUE(IsPendingSeek()); | |
1707 | |
1708 player_.OnDemuxerSeekDone(expected_preroll_timestamp); | |
1709 EXPECT_FALSE(player_.IsPlaying()); | |
1710 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
1711 EXPECT_FALSE(IsPendingSeek()); | |
1712 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp()); | |
1713 | |
1714 // Player should begin prefetch and resume preroll upon Start(). | |
1715 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1716 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
1717 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1718 StartVideoDecoderJob(); | |
1719 CreateNextTextureAndSetVideoSurface(); | |
1720 EXPECT_TRUE(GetMediaDecoderJob(false)); | |
1721 EXPECT_FALSE(IsPendingSeek()); | |
1722 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1723 EXPECT_TRUE(IsPrerolling(false)); | |
1724 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp()); | |
1725 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime()); | |
1726 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1727 | |
1728 // No further seek should have been requested since BrowserSeekPlayer(). | |
1729 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1730 } | |
1731 | |
1732 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) { | |
1733 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
1734 | |
1735 // Test that if Release() occurs after a browser seek's DemuxerSeek IPC | |
1736 // request has been sent, that the seek survives the Release(). Also, if | |
1737 // OnDemuxerSeekDone() does not occur until after the next Start(), then the | |
1738 // player remains pending seek done and, after OnDemuxerSeekDone(), resumes | |
1739 // correct post-seek preroll. | |
1740 // Note, the SeekToThenReleaseThenDemuxerSeek* tests, above, cover the | |
1741 // case where seek request has not yet been sent at time of Release(). Browser | |
1742 // seeks use similar logic, so no extra test coverage is deemed necessary. On | |
1743 // removal of browser seeks, consider retaining a regular seek version of this | |
1744 // test. | |
1745 | |
1746 // BIG TODO | |
1747 BrowserSeekPlayer(false); | |
1748 EXPECT_FALSE(GetMediaDecoderJob(false)); // It is reset pending the seek. | |
1749 EXPECT_TRUE(IsPendingSeek()); | |
1750 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime(); | |
1751 | |
1752 player_.Release(); | |
1753 EXPECT_FALSE(player_.IsPlaying()); | |
1754 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
qinmin
2013/10/30 23:07:48
lots of the testing code are testing the same init
wolenetz
2013/10/31 01:39:11
Yes, indeed. I've coalesced many of the duplicate
| |
1755 EXPECT_TRUE(IsPendingSeek()); | |
1756 | |
1757 StartVideoDecoderJob(); | |
1758 CreateNextTextureAndSetVideoSurface(); | |
1759 EXPECT_FALSE(GetMediaDecoderJob(false)); | |
1760 EXPECT_TRUE(IsPendingSeek()); | |
1761 EXPECT_FALSE(IsPendingPrefetchRequest()); | |
1762 EXPECT_FALSE(IsPendingPrefetchDone()); | |
1763 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp()); | |
1764 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
1765 | |
1766 player_.OnDemuxerSeekDone(expected_preroll_timestamp); | |
1767 EXPECT_TRUE(GetMediaDecoderJob(false)); | |
1768 EXPECT_FALSE(IsPendingSeek()); | |
1769 EXPECT_TRUE(IsPendingPrefetchDone()); | |
1770 EXPECT_TRUE(IsPrerolling(false)); | |
1771 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp()); | |
1772 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime()); | |
1773 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
1774 | |
1775 // No further seek should have been requested since BrowserSeekPlayer(). | |
1776 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
1777 } | |
1778 | |
1382 // TODO(xhwang): Enable this test when the test devices are updated. | 1779 // TODO(xhwang): Enable this test when the test devices are updated. |
1383 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) { | 1780 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) { |
1384 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) { | 1781 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) { |
1385 LOG(INFO) << "Could not run test - not supported on device."; | 1782 LOG(INFO) << "Could not run test - not supported on device."; |
1386 return; | 1783 return; |
1387 } | 1784 } |
1388 | 1785 |
1389 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, | 1786 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
1390 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; | 1787 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
1391 | 1788 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1446 | 1843 |
1447 std::vector<std::string> codec_avc(1, "avc1"); | 1844 std::vector<std::string> codec_avc(1, "avc1"); |
1448 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); | 1845 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); |
1449 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); | 1846 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); |
1450 } | 1847 } |
1451 | 1848 |
1452 // TODO(xhwang): Are these IsTypeSupported tests device specific? | 1849 // TODO(xhwang): Are these IsTypeSupported tests device specific? |
1453 // TODO(xhwang): Add more IsTypeSupported tests. | 1850 // TODO(xhwang): Add more IsTypeSupported tests. |
1454 | 1851 |
1455 } // namespace media | 1852 } // namespace media |
OLD | NEW |