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

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: Address comments and nits from PS7 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
« no previous file with comments | « media/base/android/media_source_player.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "media/base/android/media_codec_bridge.h" 10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_drm_bridge.h" 11 #include "media/base/android/media_drm_bridge.h"
12 #include "media/base/android/media_player_manager.h" 12 #include "media/base/android/media_player_manager.h"
13 #include "media/base/android/media_source_player.h" 13 #include "media/base/android/media_source_player.h"
14 #include "media/base/bind_to_loop.h"
14 #include "media/base/decoder_buffer.h" 15 #include "media/base/decoder_buffer.h"
15 #include "media/base/test_data_util.h" 16 #include "media/base/test_data_util.h"
16 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
17 #include "ui/gl/android/surface_texture.h" 18 #include "ui/gl/android/surface_texture.h"
18 19
19 namespace media { 20 namespace media {
20 21
21 // Helper macro to skip the test if MediaCodecBridge isn't available. 22 // Helper macro to skip the test if MediaCodecBridge isn't available.
22 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \ 23 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
23 do { \ 24 do { \
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 136
136 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); 137 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
137 }; 138 };
138 139
139 class MediaSourcePlayerTest : public testing::Test { 140 class MediaSourcePlayerTest : public testing::Test {
140 public: 141 public:
141 MediaSourcePlayerTest() 142 MediaSourcePlayerTest()
142 : manager_(&message_loop_), 143 : manager_(&message_loop_),
143 demuxer_(new MockDemuxerAndroid(&message_loop_)), 144 demuxer_(new MockDemuxerAndroid(&message_loop_)),
144 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)), 145 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)),
146 decoder_callback_hook_executed_(false),
145 surface_texture_a_is_next_(true) {} 147 surface_texture_a_is_next_(true) {}
146 virtual ~MediaSourcePlayerTest() {} 148 virtual ~MediaSourcePlayerTest() {}
147 149
148 protected: 150 protected:
149 // Get the decoder job from the MediaSourcePlayer. 151 // Get the decoder job from the MediaSourcePlayer.
150 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) { 152 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) {
151 if (is_audio) { 153 if (is_audio) {
152 return reinterpret_cast<MediaDecoderJob*>( 154 return reinterpret_cast<MediaDecoderJob*>(
153 player_.audio_decoder_job_.get()); 155 player_.audio_decoder_job_.get());
154 } 156 }
155 return reinterpret_cast<MediaDecoderJob*>( 157 return reinterpret_cast<MediaDecoderJob*>(
156 player_.video_decoder_job_.get()); 158 player_.video_decoder_job_.get());
157 } 159 }
158 160
159 // Get the per-job prerolling status from the MediaSourcePlayer's job matching 161 // 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. 162 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
161 bool IsPrerolling(bool is_audio) { 163 bool IsPrerolling(bool is_audio) {
162 return GetMediaDecoderJob(is_audio)->prerolling(); 164 return GetMediaDecoderJob(is_audio)->prerolling();
163 } 165 }
164 166
165 // Get the preroll timestamp from the MediaSourcePlayer. 167 // Get the preroll timestamp from the MediaSourcePlayer.
166 base::TimeDelta GetPrerollTimestamp() { 168 base::TimeDelta GetPrerollTimestamp() {
167 return player_.preroll_timestamp_; 169 return player_.preroll_timestamp_;
168 } 170 }
169 171
172 // Simulate player has reached starvation timeout.
173 void TriggerPlayerStarvation() {
174 player_.decoder_starvation_callback_.Cancel();
175 player_.OnDecoderStarved();
176 }
177
178 // Release() the player.
179 void ReleasePlayer() {
180 EXPECT_TRUE(player_.IsPlaying());
181 player_.Release();
182 EXPECT_FALSE(player_.IsPlaying());
183 EXPECT_FALSE(GetMediaDecoderJob(true));
184 EXPECT_FALSE(GetMediaDecoderJob(false));
185 }
186
187 // Upon the next successful decode callback, post a task to call Release()
188 // on the |player_|. TEST_F's do not have access to the private player
189 // members, hence this helper method.
190 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
191 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
192 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
193 player_.set_decode_callback_for_testing(media::BindToLoop(
194 message_loop_.message_loop_proxy(),
195 base::Bind(
196 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification,
197 base::Unretained(this))));
198 }
199
200 // Asynch test callback posted upon decode completion to verify that a pending
201 // prefetch done event is cleared across |player_|'s Release(). This helps
202 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
203 void ReleaseWithPendingPrefetchDoneVerification() {
204 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
205 ReleasePlayer();
206 EXPECT_FALSE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
207 EXPECT_FALSE(decoder_callback_hook_executed_);
208 decoder_callback_hook_executed_ = true;
209 }
210
170 DemuxerConfigs CreateAudioDemuxerConfigs() { 211 DemuxerConfigs CreateAudioDemuxerConfigs() {
171 DemuxerConfigs configs; 212 DemuxerConfigs configs;
172 configs.audio_codec = kCodecVorbis; 213 configs.audio_codec = kCodecVorbis;
173 configs.audio_channels = 2; 214 configs.audio_channels = 2;
174 configs.audio_sampling_rate = 44100; 215 configs.audio_sampling_rate = 44100;
175 configs.is_audio_encrypted = false; 216 configs.is_audio_encrypted = false;
176 configs.duration_ms = kDefaultDurationInMs; 217 configs.duration_ms = kDefaultDurationInMs;
177 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata"); 218 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata");
178 configs.audio_extra_data = std::vector<uint8>( 219 configs.audio_extra_data = std::vector<uint8>(
179 buffer->data(), 220 buffer->data(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 301 }
261 302
262 DemuxerData CreateAbortedAck(bool is_audio) { 303 DemuxerData CreateAbortedAck(bool is_audio) {
263 DemuxerData data; 304 DemuxerData data;
264 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO; 305 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
265 data.access_units.resize(1); 306 data.access_units.resize(1);
266 data.access_units[0].status = DemuxerStream::kAborted; 307 data.access_units[0].status = DemuxerStream::kAborted;
267 return data; 308 return data;
268 } 309 }
269 310
311 // Helper method for use at test start. It starts an audio decoder job and
312 // immediately feeds it some data to decode. Then, without letting the decoder
313 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
314 // the player should not yet have sent the DemuxerSeek IPC request, though
315 // seek event should be pending. The audio decoder job will also still be
316 // decoding.
317 void StartAudioDecoderJobAndSeekToWhileDecoding(
318 const base::TimeDelta& seek_time) {
319 EXPECT_FALSE(GetMediaDecoderJob(true));
320 EXPECT_FALSE(player_.IsPlaying());
321 EXPECT_EQ(0, demuxer_->num_data_requests());
322 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
323 EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
324 StartAudioDecoderJob();
325 EXPECT_TRUE(GetMediaDecoderJob(true));
326 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
327 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
328 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
329 player_.SeekTo(seek_time);
330 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
331 EXPECT_EQ(1, demuxer_->num_data_requests());
332 EXPECT_EQ(0, demuxer_->num_seek_requests());
333 }
334
270 // Seek, including simulated receipt of |kAborted| read between SeekTo() 335 // Seek, including simulated receipt of |kAborted| read between SeekTo()
271 // and OnDemuxerSeekDone(). Use this helper method only when the player 336 // and OnDemuxerSeekDone(). Use this helper method only when the player
272 // already has created the decoder job. 337 // already has created the decoder job.
273 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) { 338 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) {
274 EXPECT_TRUE(GetMediaDecoderJob(is_audio)); 339 EXPECT_TRUE(GetMediaDecoderJob(is_audio));
275 340
276 int original_num_seeks = demuxer_->num_seek_requests(); 341 int original_num_seeks = demuxer_->num_seek_requests();
277 int original_num_data_requests = demuxer_->num_data_requests(); 342 int original_num_data_requests = demuxer_->num_data_requests();
278 343
279 // Initiate a seek. Skip the round-trip of requesting seek from renderer. 344 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 demuxer_->num_browser_seek_requests(); 394 demuxer_->num_browser_seek_requests();
330 395
331 EXPECT_FALSE(GetMediaDecoderJob(false)); 396 EXPECT_FALSE(GetMediaDecoderJob(false));
332 CreateNextTextureAndSetVideoSurface(); 397 CreateNextTextureAndSetVideoSurface();
333 StartVideoDecoderJob(); 398 StartVideoDecoderJob();
334 EXPECT_TRUE(GetMediaDecoderJob(false)); 399 EXPECT_TRUE(GetMediaDecoderJob(false));
335 expected_num_data_requests++; 400 expected_num_data_requests++;
336 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); 401 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
337 402
338 if (trigger_with_release_start) { 403 if (trigger_with_release_start) {
339 player_.Release(); 404 ReleasePlayer();
340 405
341 // Simulate demuxer's response to the video data request. 406 // Simulate demuxer's response to the video data request.
342 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); 407 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
343 EXPECT_FALSE(GetMediaDecoderJob(false)); 408 EXPECT_FALSE(GetMediaDecoderJob(false));
344 EXPECT_FALSE(player_.IsPlaying()); 409 EXPECT_FALSE(player_.IsPlaying());
345 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests()); 410 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
346 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); 411 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
347 412
348 CreateNextTextureAndSetVideoSurface(); 413 CreateNextTextureAndSetVideoSurface();
349 player_.Start(); 414 player_.Start();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 526 }
462 527
463 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, 528 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid,
464 const std::string& security_level, 529 const std::string& security_level,
465 const std::string& container, 530 const std::string& container,
466 const std::vector<std::string>& codecs) { 531 const std::vector<std::string>& codecs) {
467 return MediaSourcePlayer::IsTypeSupported( 532 return MediaSourcePlayer::IsTypeSupported(
468 scheme_uuid, security_level, container, codecs); 533 scheme_uuid, security_level, container, codecs);
469 } 534 }
470 535
471 protected:
472 base::MessageLoop message_loop_; 536 base::MessageLoop message_loop_;
473 MockMediaPlayerManager manager_; 537 MockMediaPlayerManager manager_;
474 MockDemuxerAndroid* demuxer_; // Owned by |player_|. 538 MockDemuxerAndroid* demuxer_; // Owned by |player_|.
475 MediaSourcePlayer player_; 539 MediaSourcePlayer player_;
476 540
541 // Track whether a possibly asynch decoder callback test hook has run.
542 bool decoder_callback_hook_executed_;
543
477 // We need to keep the surface texture while the decoder is actively decoding. 544 // 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 545 // Otherwise, it may trigger unexpected crashes on some devices. To switch
479 // surfaces, tests need to create a new surface texture without releasing 546 // surfaces, tests need to create a new surface texture without releasing
480 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle 547 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
481 // between two surface textures, only replacing the N-2 texture. Assumption is 548 // 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 549 // that no more than N-1 texture is in use by decoder when
483 // CreateNextTextureAndSetVideoSurface() is called. 550 // CreateNextTextureAndSetVideoSurface() is called.
484 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_; 551 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
485 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_; 552 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
486 bool surface_texture_a_is_next_; 553 bool surface_texture_a_is_next_;
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 972
906 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) { 973 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
907 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 974 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
908 975
909 // Test that the decoder should not crash if demuxer data arrives after 976 // Test that the decoder should not crash if demuxer data arrives after
910 // Release(). 977 // Release().
911 StartAudioDecoderJob(); 978 StartAudioDecoderJob();
912 EXPECT_EQ(1, demuxer_->num_data_requests()); 979 EXPECT_EQ(1, demuxer_->num_data_requests());
913 EXPECT_TRUE(GetMediaDecoderJob(true)); 980 EXPECT_TRUE(GetMediaDecoderJob(true));
914 981
915 player_.Release(); 982 ReleasePlayer();
916 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); 983 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
917 984
918 // The decoder job should have been released. 985 // The decoder job should have been released.
919 EXPECT_FALSE(player_.IsPlaying()); 986 EXPECT_FALSE(player_.IsPlaying());
920 EXPECT_EQ(1, demuxer_->num_data_requests()); 987 EXPECT_EQ(1, demuxer_->num_data_requests());
921 988
922 // No seek requests should have occurred. 989 // No seek requests should have occurred.
923 EXPECT_EQ(0, demuxer_->num_seek_requests()); 990 EXPECT_EQ(0, demuxer_->num_seek_requests());
924 } 991 }
925 992
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) { 1024 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) {
958 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1025 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
959 1026
960 // Test that no seek is requested if player Release() + Start() occurs prior 1027 // Test that no seek is requested if player Release() + Start() occurs prior
961 // to receiving any data. 1028 // to receiving any data.
962 CreateNextTextureAndSetVideoSurface(); 1029 CreateNextTextureAndSetVideoSurface();
963 StartVideoDecoderJob(); 1030 StartVideoDecoderJob();
964 EXPECT_EQ(1, demuxer_->num_data_requests()); 1031 EXPECT_EQ(1, demuxer_->num_data_requests());
965 EXPECT_TRUE(GetMediaDecoderJob(false)); 1032 EXPECT_TRUE(GetMediaDecoderJob(false));
966 1033
967 player_.Release(); 1034 ReleasePlayer();
968 EXPECT_FALSE(player_.IsPlaying());
969 1035
970 // Pass a new non-empty surface. 1036 // Pass a new non-empty surface.
971 CreateNextTextureAndSetVideoSurface(); 1037 CreateNextTextureAndSetVideoSurface();
972 1038
973 player_.Start(); 1039 player_.Start();
974 1040
975 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream 1041 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream
976 // should be prevented. See http://crbug.com/306314. 1042 // should be prevented. See http://crbug.com/306314.
977 EXPECT_EQ(2, demuxer_->num_data_requests()); 1043 EXPECT_EQ(2, demuxer_->num_data_requests());
978 1044
979 EXPECT_EQ(0, demuxer_->num_seek_requests()); 1045 EXPECT_EQ(0, demuxer_->num_seek_requests());
980 EXPECT_TRUE(GetMediaDecoderJob(false)); 1046 EXPECT_TRUE(GetMediaDecoderJob(false));
981 } 1047 }
982 1048
983 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) { 1049 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
984 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1050 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
985 1051
986 // Test that one browser seek is requested if player Release() + Start(), with 1052 // Test that one browser seek is requested if player Release() + Start(), with
987 // video data received between Release() and Start(). 1053 // video data received between Release() and Start().
988 BrowserSeekPlayer(true); 1054 BrowserSeekPlayer(true);
989 EXPECT_FALSE(GetMediaDecoderJob(false));
990 EXPECT_EQ(1, demuxer_->num_data_requests()); 1055 EXPECT_EQ(1, demuxer_->num_data_requests());
991 1056
992 // Simulate browser seek is done and confirm player requests more data. 1057 // Simulate browser seek is done and confirm player requests more data.
993 player_.OnDemuxerSeekDone(base::TimeDelta()); 1058 player_.OnDemuxerSeekDone(base::TimeDelta());
994 EXPECT_TRUE(GetMediaDecoderJob(false)); 1059 EXPECT_TRUE(GetMediaDecoderJob(false));
995 EXPECT_EQ(2, demuxer_->num_data_requests()); 1060 EXPECT_EQ(2, demuxer_->num_data_requests());
996 EXPECT_EQ(1, demuxer_->num_seek_requests()); 1061 EXPECT_EQ(1, demuxer_->num_seek_requests());
997 } 1062 }
998 1063
999 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) { 1064 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 if (i == 1) { 1198 if (i == 1) {
1134 // While still prerolling, Release() and Start() the player. 1199 // While still prerolling, Release() and Start() the player.
1135 // TODO(qinmin): Simulation of multiple in-flight data requests (one from 1200 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1136 // before Release(), one from after Start()) is not included here, and 1201 // before Release(), one from after Start()) is not included here, and
1137 // neither is any data enqueued for later decode if it arrives after 1202 // neither is any data enqueued for later decode if it arrives after
1138 // Release() and before Start(). See http://crbug.com/306314. Assumption 1203 // Release() and before Start(). See http://crbug.com/306314. Assumption
1139 // for this test, to prevent flakiness until the bug is fixed, is the 1204 // for this test, to prevent flakiness until the bug is fixed, is the
1140 // first request's data arrives before Start(). Though that data is not 1205 // first request's data arrives before Start(). Though that data is not
1141 // seen by decoder, this assumption allows preroll continuation 1206 // seen by decoder, this assumption allows preroll continuation
1142 // verification and prevents multiple in-flight data requests. 1207 // verification and prevents multiple in-flight data requests.
1143 player_.Release(); 1208 ReleasePlayer();
1144 player_.OnDemuxerDataAvailable(data); 1209 player_.OnDemuxerDataAvailable(data);
1145 message_loop_.RunUntilIdle(); 1210 message_loop_.RunUntilIdle();
1146 EXPECT_FALSE(GetMediaDecoderJob(true)); 1211 EXPECT_FALSE(GetMediaDecoderJob(true));
1147 StartAudioDecoderJob(); 1212 StartAudioDecoderJob();
1148 EXPECT_TRUE(GetMediaDecoderJob(true)); 1213 EXPECT_TRUE(GetMediaDecoderJob(true));
1149 } else { 1214 } else {
1150 player_.OnDemuxerDataAvailable(data); 1215 player_.OnDemuxerDataAvailable(data);
1151 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); 1216 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1152 message_loop_.Run(); 1217 message_loop_.Run();
1153 } 1218 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs()); 1437 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1373 MediaDecoderJob* second_job = GetMediaDecoderJob(false); 1438 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1374 EXPECT_NE(first_job, second_job); 1439 EXPECT_NE(first_job, second_job);
1375 EXPECT_TRUE(second_job); 1440 EXPECT_TRUE(second_job);
1376 1441
1377 EXPECT_EQ(3, demuxer_->num_data_requests()); 1442 EXPECT_EQ(3, demuxer_->num_data_requests());
1378 EXPECT_EQ(1, demuxer_->num_config_requests()); 1443 EXPECT_EQ(1, demuxer_->num_config_requests());
1379 EXPECT_EQ(0, demuxer_->num_seek_requests()); 1444 EXPECT_EQ(0, demuxer_->num_seek_requests());
1380 } 1445 }
1381 1446
1447 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
1448 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1449
1450 // Test if OnPrefetchDone() had already been posted before and is executed
1451 // after Release(), then player does not DCHECK. This test is fragile to
1452 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
1453 // is posted to run |prefetch_cb| if the job already HasData().
1454 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
1455 // becomes obsolete. See http://crbug.com/304234.
1456 StartAudioDecoderJob();
1457
1458 // Escape the original prefetch by decoding a single access unit.
1459 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1460 message_loop_.Run();
1461
1462 // Prime the job with a few more access units, so that a later prefetch,
1463 // triggered by starvation to simulate decoder underrun, can trivially
1464 // post task to run OnPrefetchDone().
1465 player_.OnDemuxerDataAvailable(
1466 CreateReadFromDemuxerAckWithConfigChanged(true, 4));
1467 EXPECT_TRUE(GetMediaDecoderJob(true) &&
1468 GetMediaDecoderJob(true)->is_decoding());
1469
1470 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
1471 // The prefetch and posting of OnPrefetchDone() will not occur until next
1472 // MediaDecoderCallBack() occurs.
1473 TriggerPlayerStarvation();
1474
1475 // Upon the next successful decode callback, post a task to call Release() on
1476 // the |player_|, such that the trivial OnPrefetchDone() task posting also
1477 // occurs and should execute after the Release().
1478 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
1479
1480 while (GetMediaDecoderJob(true))
1481 message_loop_.RunUntilIdle();
1482 EXPECT_TRUE(decoder_callback_hook_executed_);
1483 EXPECT_EQ(2, demuxer_->num_data_requests());
1484
1485 // Player should have no decoder job until after Start().
1486 StartAudioDecoderJob();
1487 EXPECT_TRUE(GetMediaDecoderJob(true));
1488 }
1489
1490 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
1491 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1492
1493 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1494 // has not yet been sent, then the seek request is sent after Release(). Also,
1495 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
1496 // will resume correct post-seek preroll upon Start().
1497 StartAudioDecoderJobAndSeekToWhileDecoding(
1498 base::TimeDelta::FromMilliseconds(100));
1499 ReleasePlayer();
1500 EXPECT_EQ(1, demuxer_->num_seek_requests());
1501
1502 player_.OnDemuxerSeekDone(kNoTimestamp());
1503 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1504 EXPECT_FALSE(GetMediaDecoderJob(true));
1505 EXPECT_FALSE(player_.IsPlaying());
1506
1507 // Player should begin prefetch and resume preroll upon Start().
1508 EXPECT_EQ(1, demuxer_->num_data_requests());
1509 StartAudioDecoderJob();
1510 EXPECT_TRUE(GetMediaDecoderJob(true));
1511 EXPECT_TRUE(IsPrerolling(true));
1512 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1513 EXPECT_EQ(2, demuxer_->num_data_requests());
1514
1515 // No further seek should have been requested since Release(), above.
1516 EXPECT_EQ(1, demuxer_->num_seek_requests());
1517 }
1518
1519 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
1520 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1521
1522 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1523 // has not yet been sent, then the seek request is sent after Release(). Also,
1524 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
1525 // then the player remains pending seek done until (and resumes correct
1526 // post-seek preroll after) OnDemuxerSeekDone().
1527 StartAudioDecoderJobAndSeekToWhileDecoding(
1528 base::TimeDelta::FromMilliseconds(100));
1529 ReleasePlayer();
1530 EXPECT_EQ(1, demuxer_->num_seek_requests());
1531
1532 // Player should not prefetch upon Start() nor create the decoder job, due to
1533 // awaiting DemuxerSeekDone.
1534 StartAudioDecoderJob();
1535 EXPECT_FALSE(GetMediaDecoderJob(true));
1536 EXPECT_EQ(1, demuxer_->num_data_requests());
1537
1538 player_.OnDemuxerSeekDone(kNoTimestamp());
1539 EXPECT_TRUE(GetMediaDecoderJob(true));
1540 EXPECT_TRUE(IsPrerolling(true));
1541 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1542 EXPECT_EQ(2, demuxer_->num_data_requests());
1543
1544 // No further seek should have been requested since Release(), above.
1545 EXPECT_EQ(1, demuxer_->num_seek_requests());
1546 }
1547
1548 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) {
1549 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1550
1551 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
1552 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
1553 // player will resume correct post-seek preroll upon Start().
1554 StartAudioDecoderJobAndSeekToWhileDecoding(
1555 base::TimeDelta::FromMilliseconds(100));
1556 while (GetMediaDecoderJob(true)->is_decoding())
1557 message_loop_.RunUntilIdle();
1558 EXPECT_EQ(1, demuxer_->num_seek_requests());
1559
1560 ReleasePlayer();
1561 player_.OnDemuxerSeekDone(kNoTimestamp());
1562 EXPECT_FALSE(player_.IsPlaying());
1563 EXPECT_FALSE(GetMediaDecoderJob(true));
1564 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1565
1566 // Player should begin prefetch and resume preroll upon Start().
1567 EXPECT_EQ(1, demuxer_->num_data_requests());
1568 StartAudioDecoderJob();
1569 EXPECT_TRUE(GetMediaDecoderJob(true));
1570 EXPECT_TRUE(IsPrerolling(true));
1571 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1572 EXPECT_EQ(2, demuxer_->num_data_requests());
1573
1574 // No further seek should have been requested since before Release(), above.
1575 EXPECT_EQ(1, demuxer_->num_seek_requests());
1576 }
1577
1578 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) {
1579 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1580
1581 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
1582 // request OnDemuxerSeekDone() does not occur until after the next Start(),
1583 // then the player remains pending seek done until (and resumes correct
1584 // post-seek preroll after) OnDemuxerSeekDone().
1585 StartAudioDecoderJobAndSeekToWhileDecoding(
1586 base::TimeDelta::FromMilliseconds(100));
1587 while (GetMediaDecoderJob(true)->is_decoding())
1588 message_loop_.RunUntilIdle();
1589 EXPECT_EQ(1, demuxer_->num_seek_requests());
1590
1591 ReleasePlayer();
1592 StartAudioDecoderJob();
1593 EXPECT_FALSE(GetMediaDecoderJob(true));
1594 EXPECT_EQ(1, demuxer_->num_data_requests());
1595
1596 player_.OnDemuxerSeekDone(kNoTimestamp());
1597 EXPECT_TRUE(GetMediaDecoderJob(true));
1598 EXPECT_TRUE(IsPrerolling(true));
1599 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1600 EXPECT_EQ(2, demuxer_->num_data_requests());
1601
1602 // No further seek should have been requested since before Release(), above.
1603 EXPECT_EQ(1, demuxer_->num_seek_requests());
1604 }
1605
1606 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) {
1607 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1608
1609 // Test if Release() occurs after |kConfigChanged| detected, new configs
1610 // requested of demuxer, and the requested configs arrive before the next
1611 // Start(), then the player completes the pending config change processing on
1612 // their receipt.
1613 StartConfigChange(true, true, 0);
1614 ReleasePlayer();
1615
1616 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
1617 EXPECT_FALSE(GetMediaDecoderJob(true));
1618 EXPECT_FALSE(player_.IsPlaying());
1619 EXPECT_EQ(1, demuxer_->num_data_requests());
1620
1621 // Player should resume upon Start(), even without further configs supplied.
1622 player_.Start();
1623 EXPECT_TRUE(GetMediaDecoderJob(true));
1624 EXPECT_TRUE(player_.IsPlaying());
1625 EXPECT_EQ(2, demuxer_->num_data_requests());
1626
1627 // No further config request should have occurred since StartConfigChange().
1628 EXPECT_EQ(1, demuxer_->num_config_requests());
1629 }
1630
1631 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
1632 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1633
1634 // Test if Release() occurs after |kConfigChanged| detected, new configs
1635 // requested of demuxer, and the requested configs arrive after the next
1636 // Start(), then the player pends job creation until the new configs arrive.
1637 StartConfigChange(true, true, 0);
1638 ReleasePlayer();
1639
1640 player_.Start();
1641 EXPECT_TRUE(player_.IsPlaying());
1642 EXPECT_FALSE(GetMediaDecoderJob(true));
1643 EXPECT_EQ(1, demuxer_->num_data_requests());
1644
1645 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
1646 EXPECT_TRUE(GetMediaDecoderJob(true));
1647 EXPECT_EQ(2, demuxer_->num_data_requests());
1648
1649 // No further config request should have occurred since StartConfigChange().
1650 EXPECT_EQ(1, demuxer_->num_config_requests());
1651 }
1652
1653 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
1654 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1655
1656 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1657 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
1658 // before the next Start()+SetVideoSurface(), then the player will resume
1659 // correct post-seek preroll upon Start()+SetVideoSurface().
1660 BrowserSeekPlayer(false);
1661 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1662 ReleasePlayer();
1663
1664 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1665 EXPECT_FALSE(player_.IsPlaying());
1666 EXPECT_FALSE(GetMediaDecoderJob(false));
1667 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1668
1669 // Player should begin prefetch and resume preroll upon Start().
1670 EXPECT_EQ(1, demuxer_->num_data_requests());
1671 StartVideoDecoderJob();
1672 CreateNextTextureAndSetVideoSurface();
1673 EXPECT_TRUE(GetMediaDecoderJob(false));
1674 EXPECT_TRUE(IsPrerolling(false));
1675 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1676 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1677 EXPECT_EQ(2, demuxer_->num_data_requests());
1678
1679 // No further seek should have been requested since BrowserSeekPlayer().
1680 EXPECT_EQ(1, demuxer_->num_seek_requests());
1681 }
1682
1683 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
1684 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1685
1686 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1687 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
1688 // occur until after the next Start()+SetVideoSurface(), then the player
1689 // remains pending seek done until (and resumes correct post-seek preroll
1690 // after) OnDemuxerSeekDone().
1691 BrowserSeekPlayer(false);
1692 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1693 ReleasePlayer();
1694
1695 StartVideoDecoderJob();
1696 CreateNextTextureAndSetVideoSurface();
1697 EXPECT_FALSE(GetMediaDecoderJob(false));
1698 EXPECT_EQ(1, demuxer_->num_data_requests());
1699
1700 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1701 EXPECT_TRUE(GetMediaDecoderJob(false));
1702 EXPECT_TRUE(IsPrerolling(false));
1703 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1704 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1705 EXPECT_EQ(2, demuxer_->num_data_requests());
1706
1707 // No further seek should have been requested since BrowserSeekPlayer().
1708 EXPECT_EQ(1, demuxer_->num_seek_requests());
1709 }
1710
1382 // TODO(xhwang): Enable this test when the test devices are updated. 1711 // TODO(xhwang): Enable this test when the test devices are updated.
1383 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) { 1712 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) {
1384 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) { 1713 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
1385 LOG(INFO) << "Could not run test - not supported on device."; 1714 LOG(INFO) << "Could not run test - not supported on device.";
1386 return; 1715 return;
1387 } 1716 }
1388 1717
1389 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, 1718 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
1390 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; 1719 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
1391 1720
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 1775
1447 std::vector<std::string> codec_avc(1, "avc1"); 1776 std::vector<std::string> codec_avc(1, "avc1");
1448 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); 1777 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc));
1449 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); 1778 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc));
1450 } 1779 }
1451 1780
1452 // TODO(xhwang): Are these IsTypeSupported tests device specific? 1781 // TODO(xhwang): Are these IsTypeSupported tests device specific?
1453 // TODO(xhwang): Add more IsTypeSupported tests. 1782 // TODO(xhwang): Add more IsTypeSupported tests.
1454 1783
1455 } // namespace media 1784 } // namespace media
OLDNEW
« no previous file with comments | « 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