OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |