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

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 PS6 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/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 void SetTestDecodeCallback(const base::Closure& test_decode_cb) {
188 player_.set_decode_callback_for_testing(test_decode_cb);
acolwell GONE FROM CHROMIUM 2013/10/31 17:54:00 nit: This is only called in one location. Please j
wolenetz 2013/11/01 20:45:28 I did this to keep MSP::set_decode_callback_for_te
189 }
190
191 // Asynch test callback posted upon decode completion to verify that a pending
192 // prefetch done event is cleared across |player_|'s Release(). This helps
193 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
194 void ReleaseWithPendingPrefetchDoneVerification() {
195 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
196 ReleasePlayer();
197 EXPECT_FALSE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
198 EXPECT_FALSE(decoder_callback_hook_executed_);
199 decoder_callback_hook_executed_ = true;
200 }
201
170 DemuxerConfigs CreateAudioDemuxerConfigs() { 202 DemuxerConfigs CreateAudioDemuxerConfigs() {
171 DemuxerConfigs configs; 203 DemuxerConfigs configs;
172 configs.audio_codec = kCodecVorbis; 204 configs.audio_codec = kCodecVorbis;
173 configs.audio_channels = 2; 205 configs.audio_channels = 2;
174 configs.audio_sampling_rate = 44100; 206 configs.audio_sampling_rate = 44100;
175 configs.is_audio_encrypted = false; 207 configs.is_audio_encrypted = false;
176 configs.duration_ms = kDefaultDurationInMs; 208 configs.duration_ms = kDefaultDurationInMs;
177 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata"); 209 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vorbis-extradata");
178 configs.audio_extra_data = std::vector<uint8>( 210 configs.audio_extra_data = std::vector<uint8>(
179 buffer->data(), 211 buffer->data(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 292 }
261 293
262 DemuxerData CreateAbortedAck(bool is_audio) { 294 DemuxerData CreateAbortedAck(bool is_audio) {
263 DemuxerData data; 295 DemuxerData data;
264 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO; 296 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
265 data.access_units.resize(1); 297 data.access_units.resize(1);
266 data.access_units[0].status = DemuxerStream::kAborted; 298 data.access_units[0].status = DemuxerStream::kAborted;
267 return data; 299 return data;
268 } 300 }
269 301
302 // Helper method for use at test start. It starts an audio decoder job and
303 // immediately feeds it some data to decode. Then, without letting the decoder
304 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
305 // the player should not yet have sent the DemuxerSeek IPC request, though
306 // seek event should be pending. The audio decoder job will also still be
307 // decoding.
308 void StartAudioDecoderJobAndSeekToWhileDecoding(
309 const base::TimeDelta& seek_time) {
310 EXPECT_FALSE(GetMediaDecoderJob(true));
311 EXPECT_FALSE(player_.IsPlaying());
312 EXPECT_EQ(0, demuxer_->num_data_requests());
313 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
314 EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
315 StartAudioDecoderJob();
316 EXPECT_TRUE(GetMediaDecoderJob(true));
317 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
318 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
319 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
320 player_.SeekTo(seek_time);
321 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
322 EXPECT_EQ(1, demuxer_->num_data_requests());
323 EXPECT_EQ(0, demuxer_->num_seek_requests());
324 }
325
270 // Seek, including simulated receipt of |kAborted| read between SeekTo() 326 // Seek, including simulated receipt of |kAborted| read between SeekTo()
271 // and OnDemuxerSeekDone(). Use this helper method only when the player 327 // and OnDemuxerSeekDone(). Use this helper method only when the player
272 // already has created the decoder job. 328 // already has created the decoder job.
273 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) { 329 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) {
274 EXPECT_TRUE(GetMediaDecoderJob(is_audio)); 330 EXPECT_TRUE(GetMediaDecoderJob(is_audio));
275 331
276 int original_num_seeks = demuxer_->num_seek_requests(); 332 int original_num_seeks = demuxer_->num_seek_requests();
277 int original_num_data_requests = demuxer_->num_data_requests(); 333 int original_num_data_requests = demuxer_->num_data_requests();
278 334
279 // Initiate a seek. Skip the round-trip of requesting seek from renderer. 335 // 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(); 385 demuxer_->num_browser_seek_requests();
330 386
331 EXPECT_FALSE(GetMediaDecoderJob(false)); 387 EXPECT_FALSE(GetMediaDecoderJob(false));
332 CreateNextTextureAndSetVideoSurface(); 388 CreateNextTextureAndSetVideoSurface();
333 StartVideoDecoderJob(); 389 StartVideoDecoderJob();
334 EXPECT_TRUE(GetMediaDecoderJob(false)); 390 EXPECT_TRUE(GetMediaDecoderJob(false));
335 expected_num_data_requests++; 391 expected_num_data_requests++;
336 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); 392 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
337 393
338 if (trigger_with_release_start) { 394 if (trigger_with_release_start) {
339 player_.Release(); 395 ReleasePlayer();
340 396
341 // Simulate demuxer's response to the video data request. 397 // Simulate demuxer's response to the video data request.
342 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); 398 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
343 EXPECT_FALSE(GetMediaDecoderJob(false)); 399 EXPECT_FALSE(GetMediaDecoderJob(false));
344 EXPECT_FALSE(player_.IsPlaying()); 400 EXPECT_FALSE(player_.IsPlaying());
345 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests()); 401 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
346 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); 402 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
347 403
348 CreateNextTextureAndSetVideoSurface(); 404 CreateNextTextureAndSetVideoSurface();
349 player_.Start(); 405 player_.Start();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 517 }
462 518
463 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, 519 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid,
464 const std::string& security_level, 520 const std::string& security_level,
465 const std::string& container, 521 const std::string& container,
466 const std::vector<std::string>& codecs) { 522 const std::vector<std::string>& codecs) {
467 return MediaSourcePlayer::IsTypeSupported( 523 return MediaSourcePlayer::IsTypeSupported(
468 scheme_uuid, security_level, container, codecs); 524 scheme_uuid, security_level, container, codecs);
469 } 525 }
470 526
471 protected:
472 base::MessageLoop message_loop_; 527 base::MessageLoop message_loop_;
473 MockMediaPlayerManager manager_; 528 MockMediaPlayerManager manager_;
474 MockDemuxerAndroid* demuxer_; // Owned by |player_|. 529 MockDemuxerAndroid* demuxer_; // Owned by |player_|.
475 MediaSourcePlayer player_; 530 MediaSourcePlayer player_;
476 531
532 // Track whether a possibly asynch decoder callback test hook has run.
533 bool decoder_callback_hook_executed_;
534
477 // We need to keep the surface texture while the decoder is actively decoding. 535 // 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 536 // Otherwise, it may trigger unexpected crashes on some devices. To switch
479 // surfaces, tests need to create a new surface texture without releasing 537 // surfaces, tests need to create a new surface texture without releasing
480 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle 538 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
481 // between two surface textures, only replacing the N-2 texture. Assumption is 539 // 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 540 // that no more than N-1 texture is in use by decoder when
483 // CreateNextTextureAndSetVideoSurface() is called. 541 // CreateNextTextureAndSetVideoSurface() is called.
484 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_; 542 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
485 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_; 543 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
486 bool surface_texture_a_is_next_; 544 bool surface_texture_a_is_next_;
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 963
906 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) { 964 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
907 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 965 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
908 966
909 // Test that the decoder should not crash if demuxer data arrives after 967 // Test that the decoder should not crash if demuxer data arrives after
910 // Release(). 968 // Release().
911 StartAudioDecoderJob(); 969 StartAudioDecoderJob();
912 EXPECT_EQ(1, demuxer_->num_data_requests()); 970 EXPECT_EQ(1, demuxer_->num_data_requests());
913 EXPECT_TRUE(GetMediaDecoderJob(true)); 971 EXPECT_TRUE(GetMediaDecoderJob(true));
914 972
915 player_.Release(); 973 ReleasePlayer();
916 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); 974 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
917 975
918 // The decoder job should have been released. 976 // The decoder job should have been released.
919 EXPECT_FALSE(player_.IsPlaying()); 977 EXPECT_FALSE(player_.IsPlaying());
920 EXPECT_EQ(1, demuxer_->num_data_requests()); 978 EXPECT_EQ(1, demuxer_->num_data_requests());
921 979
922 // No seek requests should have occurred. 980 // No seek requests should have occurred.
923 EXPECT_EQ(0, demuxer_->num_seek_requests()); 981 EXPECT_EQ(0, demuxer_->num_seek_requests());
924 } 982 }
925 983
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) { 1015 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) {
958 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1016 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
959 1017
960 // Test that no seek is requested if player Release() + Start() occurs prior 1018 // Test that no seek is requested if player Release() + Start() occurs prior
961 // to receiving any data. 1019 // to receiving any data.
962 CreateNextTextureAndSetVideoSurface(); 1020 CreateNextTextureAndSetVideoSurface();
963 StartVideoDecoderJob(); 1021 StartVideoDecoderJob();
964 EXPECT_EQ(1, demuxer_->num_data_requests()); 1022 EXPECT_EQ(1, demuxer_->num_data_requests());
965 EXPECT_TRUE(GetMediaDecoderJob(false)); 1023 EXPECT_TRUE(GetMediaDecoderJob(false));
966 1024
967 player_.Release(); 1025 ReleasePlayer();
968 EXPECT_FALSE(player_.IsPlaying());
969 1026
970 // Pass a new non-empty surface. 1027 // Pass a new non-empty surface.
971 CreateNextTextureAndSetVideoSurface(); 1028 CreateNextTextureAndSetVideoSurface();
972 1029
973 player_.Start(); 1030 player_.Start();
974 1031
975 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream 1032 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream
976 // should be prevented. See http://crbug.com/306314. 1033 // should be prevented. See http://crbug.com/306314.
977 EXPECT_EQ(2, demuxer_->num_data_requests()); 1034 EXPECT_EQ(2, demuxer_->num_data_requests());
978 1035
979 EXPECT_EQ(0, demuxer_->num_seek_requests()); 1036 EXPECT_EQ(0, demuxer_->num_seek_requests());
980 EXPECT_TRUE(GetMediaDecoderJob(false)); 1037 EXPECT_TRUE(GetMediaDecoderJob(false));
981 } 1038 }
982 1039
983 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) { 1040 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
984 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1041 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
985 1042
986 // Test that one browser seek is requested if player Release() + Start(), with 1043 // Test that one browser seek is requested if player Release() + Start(), with
987 // video data received between Release() and Start(). 1044 // video data received between Release() and Start().
988 BrowserSeekPlayer(true); 1045 BrowserSeekPlayer(true);
989 EXPECT_FALSE(GetMediaDecoderJob(false));
990 EXPECT_EQ(1, demuxer_->num_data_requests()); 1046 EXPECT_EQ(1, demuxer_->num_data_requests());
991 1047
992 // Simulate browser seek is done and confirm player requests more data. 1048 // Simulate browser seek is done and confirm player requests more data.
993 player_.OnDemuxerSeekDone(base::TimeDelta()); 1049 player_.OnDemuxerSeekDone(base::TimeDelta());
994 EXPECT_TRUE(GetMediaDecoderJob(false)); 1050 EXPECT_TRUE(GetMediaDecoderJob(false));
995 EXPECT_EQ(2, demuxer_->num_data_requests()); 1051 EXPECT_EQ(2, demuxer_->num_data_requests());
996 EXPECT_EQ(1, demuxer_->num_seek_requests()); 1052 EXPECT_EQ(1, demuxer_->num_seek_requests());
997 } 1053 }
998 1054
999 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) { 1055 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 if (i == 1) { 1189 if (i == 1) {
1134 // While still prerolling, Release() and Start() the player. 1190 // While still prerolling, Release() and Start() the player.
1135 // TODO(qinmin): Simulation of multiple in-flight data requests (one from 1191 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1136 // before Release(), one from after Start()) is not included here, and 1192 // before Release(), one from after Start()) is not included here, and
1137 // neither is any data enqueued for later decode if it arrives after 1193 // neither is any data enqueued for later decode if it arrives after
1138 // Release() and before Start(). See http://crbug.com/306314. Assumption 1194 // Release() and before Start(). See http://crbug.com/306314. Assumption
1139 // for this test, to prevent flakiness until the bug is fixed, is the 1195 // 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 1196 // first request's data arrives before Start(). Though that data is not
1141 // seen by decoder, this assumption allows preroll continuation 1197 // seen by decoder, this assumption allows preroll continuation
1142 // verification and prevents multiple in-flight data requests. 1198 // verification and prevents multiple in-flight data requests.
1143 player_.Release(); 1199 ReleasePlayer();
1144 player_.OnDemuxerDataAvailable(data); 1200 player_.OnDemuxerDataAvailable(data);
1145 message_loop_.RunUntilIdle(); 1201 message_loop_.RunUntilIdle();
1146 EXPECT_FALSE(GetMediaDecoderJob(true)); 1202 EXPECT_FALSE(GetMediaDecoderJob(true));
1147 StartAudioDecoderJob(); 1203 StartAudioDecoderJob();
1148 EXPECT_TRUE(GetMediaDecoderJob(true)); 1204 EXPECT_TRUE(GetMediaDecoderJob(true));
1149 } else { 1205 } else {
1150 player_.OnDemuxerDataAvailable(data); 1206 player_.OnDemuxerDataAvailable(data);
1151 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); 1207 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1152 message_loop_.Run(); 1208 message_loop_.Run();
1153 } 1209 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs()); 1428 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1373 MediaDecoderJob* second_job = GetMediaDecoderJob(false); 1429 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1374 EXPECT_NE(first_job, second_job); 1430 EXPECT_NE(first_job, second_job);
1375 EXPECT_TRUE(second_job); 1431 EXPECT_TRUE(second_job);
1376 1432
1377 EXPECT_EQ(3, demuxer_->num_data_requests()); 1433 EXPECT_EQ(3, demuxer_->num_data_requests());
1378 EXPECT_EQ(1, demuxer_->num_config_requests()); 1434 EXPECT_EQ(1, demuxer_->num_config_requests());
1379 EXPECT_EQ(0, demuxer_->num_seek_requests()); 1435 EXPECT_EQ(0, demuxer_->num_seek_requests());
1380 } 1436 }
1381 1437
1438 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
1439 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1440
1441 // Test that if OnPrefetchDone() had already been posted before and is
1442 // executed after Release(), player does not DCHECK.
1443 StartAudioDecoderJob();
1444
1445 // Escape the original prefetch by decoding a single access unit.
1446 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1447 message_loop_.Run();
1448
1449 // Prime the job with a few more access units, so that a later prefetch,
1450 // triggered by starvation to simulate decoder underrun, can trivially
1451 // post task to run OnPrefetchDone().
1452 player_.OnDemuxerDataAvailable(
1453 CreateReadFromDemuxerAckWithConfigChanged(true, 4));
1454 EXPECT_TRUE(GetMediaDecoderJob(true) &&
1455 GetMediaDecoderJob(true)->is_decoding());
1456
1457 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
1458 // The prefetch and posting of OnPrefetchDone() will not occur until next
1459 // MediaDecoderCallBack() occurs.
1460 TriggerPlayerStarvation();
1461
1462 // Upon the next successful decode callback, post a task to Release()
qinmin 2013/10/31 04:12:27 nit: rephrase this. either "release |player_|" or
wolenetz 2013/11/01 20:45:28 Done.
wolenetz 2013/11/01 20:45:28 Done.
1463 // |player_|, such that the trivial OnPrefetchDone() task posting also occurs
1464 // and should execute after the Release().
1465 SetTestDecodeCallback(media::BindToLoop(
acolwell GONE FROM CHROMIUM 2013/10/31 17:54:00 Do you really need this callback? Can't you just c
wolenetz 2013/11/01 20:45:28 The problem is that RunUntilIdle() runs too much,
1466 message_loop_.message_loop_proxy(),
1467 base::Bind(
1468 &MediaSourcePlayerTest_ReleaseWithOnPrefetchDoneAlreadyPosted_Test::
1469 ReleaseWithPendingPrefetchDoneVerification,
1470 base::Unretained(this))));
1471
1472 while (GetMediaDecoderJob(true))
1473 message_loop_.RunUntilIdle();
1474 EXPECT_TRUE(decoder_callback_hook_executed_);
1475 EXPECT_EQ(2, demuxer_->num_data_requests());
1476
1477 // Player should have no decoder job until after Start().
1478 StartAudioDecoderJob();
1479 EXPECT_TRUE(GetMediaDecoderJob(true));
1480 }
1481
1482 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
1483 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1484
1485 // Test that if Release() occurs after SeekTo(), but the DemuxerSeek IPC
1486 // request has not yet been sent, that the seek request will be sent after
1487 // Release(). Also, if OnDemuxerSeekDone() occurs prior to next Start(), then
1488 // the player will resume correct post-seek preroll upon Start().
1489 StartAudioDecoderJobAndSeekToWhileDecoding(
1490 base::TimeDelta::FromMilliseconds(100));
1491 ReleasePlayer();
1492 EXPECT_EQ(1, demuxer_->num_seek_requests());
1493
1494 player_.OnDemuxerSeekDone(kNoTimestamp());
1495 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1496 EXPECT_FALSE(GetMediaDecoderJob(true));
1497 EXPECT_FALSE(player_.IsPlaying());
1498
1499 // Player should begin prefetch and resume preroll upon Start().
1500 EXPECT_EQ(1, demuxer_->num_data_requests());
1501 StartAudioDecoderJob();
1502 EXPECT_TRUE(GetMediaDecoderJob(true));
1503 EXPECT_TRUE(IsPrerolling(true));
1504 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1505 EXPECT_EQ(2, demuxer_->num_data_requests());
1506
1507 // No further seek should have been requested since Release(), above.
1508 EXPECT_EQ(1, demuxer_->num_seek_requests());
1509 }
1510
1511 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
1512 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1513
1514 // Test that if Release() occurs after SeekTo(), but the DemuxerSeek IPC
1515 // request has not yet been sent, that the seek request will be sent after
1516 // Release(). Also, if OnDemuxerSeekDone() does not occur until after the next
1517 // Start(), then the player remains pending seek done and, after
1518 // OnDemuxerSeekDone(), resumes correct post-seek preroll.
1519 StartAudioDecoderJobAndSeekToWhileDecoding(
1520 base::TimeDelta::FromMilliseconds(100));
1521 ReleasePlayer();
1522 EXPECT_EQ(1, demuxer_->num_seek_requests());
1523
1524 // Player should not prefetch upon Start() nor create the decoder job, due to
1525 // awaiting DemuxerSeekDone.
1526 StartAudioDecoderJob();
1527 EXPECT_FALSE(GetMediaDecoderJob(true));
1528 EXPECT_EQ(1, demuxer_->num_data_requests());
1529
1530 player_.OnDemuxerSeekDone(kNoTimestamp());
1531 EXPECT_TRUE(GetMediaDecoderJob(true));
1532 EXPECT_TRUE(IsPrerolling(true));
1533 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1534 EXPECT_EQ(2, demuxer_->num_data_requests());
1535
1536 // No further seek should have been requested since Release(), above.
1537 EXPECT_EQ(1, demuxer_->num_seek_requests());
1538 }
1539
1540 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) {
1541 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1542
1543 // Test that if Release() occurs after |kConfigChanged| detected and new
1544 // configs requested of demuxer, and the requested configs arrive before
1545 // the next Start(), then the player completes the pending config change
1546 // processing on their receipt.
1547 StartConfigChange(true, true, 0);
1548 ReleasePlayer();
1549
1550 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
1551 EXPECT_FALSE(GetMediaDecoderJob(true));
1552 EXPECT_FALSE(player_.IsPlaying());
1553 EXPECT_EQ(1, demuxer_->num_data_requests());
1554
1555 // Player should resume upon Start(), even without further configs supplied.
1556 player_.Start();
1557 EXPECT_TRUE(GetMediaDecoderJob(true));
1558 EXPECT_TRUE(player_.IsPlaying());
1559 EXPECT_EQ(2, demuxer_->num_data_requests());
1560
1561 // No further config request should have occurred since StartConfigChange().
1562 EXPECT_EQ(1, demuxer_->num_config_requests());
1563 }
1564
1565 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
1566 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1567
1568 // Test that if Release() occurs after |kConfigChanged| detected and new
1569 // configs requested of demuxer, and the requested configs arrive after the
1570 // next Start(), then the player pends job creation until the new configs
1571 // arrive.
1572 StartConfigChange(true, true, 0);
1573 ReleasePlayer();
1574
1575 player_.Start();
1576 EXPECT_TRUE(player_.IsPlaying());
1577 EXPECT_FALSE(GetMediaDecoderJob(true));
1578 EXPECT_EQ(1, demuxer_->num_data_requests());
1579
1580 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
1581 EXPECT_TRUE(GetMediaDecoderJob(true));
1582 EXPECT_EQ(2, demuxer_->num_data_requests());
1583
1584 // No further config request should have occurred since StartConfigChange().
1585 EXPECT_EQ(1, demuxer_->num_config_requests());
1586 }
1587
1588 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
1589 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1590
1591 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1592 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() arrives
1593 // prior to the next Start()+SetVideoSurface(), then the player will resume
1594 // correct post-seek preroll upon Start()+SetVideoSurface().
1595 // Note, the SeekToThenReleaseThenDemuxerSeek* tests, above, cover the
1596 // case where seek request has not yet been sent at time of Release(). Browser
1597 // seeks use similar logic, so no extra test coverage is deemed necessary. On
1598 // removal of browser seeks, consider retaining a regular seek version of this
acolwell GONE FROM CHROMIUM 2013/10/31 17:54:00 This is confusing to me. Does this mean a new test
wolenetz 2013/11/01 20:45:28 Oops! My 'Note' comments in these two new BrowserS
1599 // test.
1600 BrowserSeekPlayer(false);
1601 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1602 ReleasePlayer();
1603
1604 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1605 EXPECT_FALSE(player_.IsPlaying());
1606 EXPECT_FALSE(GetMediaDecoderJob(false));
1607 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1608
1609 // Player should begin prefetch and resume preroll upon Start().
1610 EXPECT_EQ(1, demuxer_->num_data_requests());
1611 StartVideoDecoderJob();
1612 CreateNextTextureAndSetVideoSurface();
1613 EXPECT_TRUE(GetMediaDecoderJob(false));
1614 EXPECT_TRUE(IsPrerolling(false));
1615 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1616 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1617 EXPECT_EQ(2, demuxer_->num_data_requests());
1618
1619 // No further seek should have been requested since BrowserSeekPlayer().
1620 EXPECT_EQ(1, demuxer_->num_seek_requests());
1621 }
1622
1623 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
1624 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1625
1626 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1627 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
1628 // occur until after the next Start()+SetVideoSurface(), then the player
1629 // remains pending seek done and, after OnDemuxerSeekDone(), resumes correct
1630 // post-seek preroll.
1631 // Note, the SeekToThenReleaseThenDemuxerSeek* tests, above, cover the
1632 // case where seek request has not yet been sent at time of Release(). Browser
1633 // seeks use similar logic, so no extra test coverage is deemed necessary. On
1634 // removal of browser seeks, consider retaining a regular seek version of this
1635 // test.
acolwell GONE FROM CHROMIUM 2013/10/31 17:54:00 ditto
wolenetz 2013/11/01 20:45:28 Done, per above. Thanks!
1636 BrowserSeekPlayer(false);
1637 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1638 ReleasePlayer();
1639
1640 StartVideoDecoderJob();
1641 CreateNextTextureAndSetVideoSurface();
1642 EXPECT_FALSE(GetMediaDecoderJob(false));
1643 EXPECT_EQ(1, demuxer_->num_data_requests());
1644
1645 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1646 EXPECT_TRUE(GetMediaDecoderJob(false));
1647 EXPECT_TRUE(IsPrerolling(false));
1648 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1649 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1650 EXPECT_EQ(2, demuxer_->num_data_requests());
1651
1652 // No further seek should have been requested since BrowserSeekPlayer().
1653 EXPECT_EQ(1, demuxer_->num_seek_requests());
1654 }
1655
1382 // TODO(xhwang): Enable this test when the test devices are updated. 1656 // TODO(xhwang): Enable this test when the test devices are updated.
1383 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) { 1657 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) {
1384 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) { 1658 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
1385 LOG(INFO) << "Could not run test - not supported on device."; 1659 LOG(INFO) << "Could not run test - not supported on device.";
1386 return; 1660 return;
1387 } 1661 }
1388 1662
1389 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, 1663 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
1390 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; 1664 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
1391 1665
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 1720
1447 std::vector<std::string> codec_avc(1, "avc1"); 1721 std::vector<std::string> codec_avc(1, "avc1");
1448 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); 1722 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc));
1449 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); 1723 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc));
1450 } 1724 }
1451 1725
1452 // TODO(xhwang): Are these IsTypeSupported tests device specific? 1726 // TODO(xhwang): Are these IsTypeSupported tests device specific?
1453 // TODO(xhwang): Add more IsTypeSupported tests. 1727 // TODO(xhwang): Add more IsTypeSupported tests.
1454 1728
1455 } // namespace media 1729 } // namespace media
OLDNEW
« media/base/android/media_source_player.h ('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