Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Side by Side Diff: media/base/android/media_source_player_unittest.cc

Issue 51613002: Abort MSP::OnPrefetchDone() if just after MSP::Release(). Let seek and config change survive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add more unit test coverage Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« media/base/android/media_source_player.cc ('K') | « media/base/android/media_source_player.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698