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/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and | 34 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and |
35 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839. | 35 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839. |
36 | 36 |
37 // Mock of MediaPlayerManager for testing purpose. | 37 // Mock of MediaPlayerManager for testing purpose. |
38 class MockMediaPlayerManager : public MediaPlayerManager { | 38 class MockMediaPlayerManager : public MediaPlayerManager { |
39 public: | 39 public: |
40 explicit MockMediaPlayerManager(base::MessageLoop* message_loop) | 40 explicit MockMediaPlayerManager(base::MessageLoop* message_loop) |
41 : message_loop_(message_loop), | 41 : message_loop_(message_loop), |
42 playback_completed_(false), | 42 playback_completed_(false), |
43 num_resources_requested_(0), | 43 num_resources_requested_(0), |
44 num_resources_released_(0) {} | 44 num_resources_released_(0), |
| 45 timestamp_updated_(false) {} |
45 virtual ~MockMediaPlayerManager() {} | 46 virtual ~MockMediaPlayerManager() {} |
46 | 47 |
47 // MediaPlayerManager implementation. | 48 // MediaPlayerManager implementation. |
48 virtual MediaResourceGetter* GetMediaResourceGetter() OVERRIDE { | 49 virtual MediaResourceGetter* GetMediaResourceGetter() OVERRIDE { |
49 return NULL; | 50 return NULL; |
50 } | 51 } |
51 virtual void OnTimeUpdate(int player_id, | 52 virtual void OnTimeUpdate(int player_id, |
52 base::TimeDelta current_time) OVERRIDE {} | 53 base::TimeDelta current_time) OVERRIDE { |
| 54 timestamp_updated_ = true; |
| 55 } |
53 virtual void OnMediaMetadataChanged( | 56 virtual void OnMediaMetadataChanged( |
54 int player_id, base::TimeDelta duration, int width, int height, | 57 int player_id, base::TimeDelta duration, int width, int height, |
55 bool success) OVERRIDE {} | 58 bool success) OVERRIDE {} |
56 virtual void OnPlaybackComplete(int player_id) OVERRIDE { | 59 virtual void OnPlaybackComplete(int player_id) OVERRIDE { |
57 playback_completed_ = true; | 60 playback_completed_ = true; |
58 if (message_loop_->is_running()) | 61 if (message_loop_->is_running()) |
59 message_loop_->Quit(); | 62 message_loop_->Quit(); |
60 } | 63 } |
61 virtual void OnMediaInterrupted(int player_id) OVERRIDE {} | 64 virtual void OnMediaInterrupted(int player_id) OVERRIDE {} |
62 virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE {} | 65 virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE {} |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 } | 100 } |
98 | 101 |
99 void OnMediaResourcesRequested(int player_id) { | 102 void OnMediaResourcesRequested(int player_id) { |
100 num_resources_requested_++; | 103 num_resources_requested_++; |
101 } | 104 } |
102 | 105 |
103 void OnMediaResourcesReleased(int player_id) { | 106 void OnMediaResourcesReleased(int player_id) { |
104 num_resources_released_++; | 107 num_resources_released_++; |
105 } | 108 } |
106 | 109 |
| 110 bool timestamp_updated() const { |
| 111 return timestamp_updated_; |
| 112 } |
| 113 |
| 114 void ResetTimestampUpdated() { |
| 115 timestamp_updated_ = false; |
| 116 } |
| 117 |
107 private: | 118 private: |
108 base::MessageLoop* message_loop_; | 119 base::MessageLoop* message_loop_; |
109 bool playback_completed_; | 120 bool playback_completed_; |
110 // The number of resource requests this object has seen. | 121 // The number of resource requests this object has seen. |
111 int num_resources_requested_; | 122 int num_resources_requested_; |
112 // The number of released resources. | 123 // The number of released resources. |
113 int num_resources_released_; | 124 int num_resources_released_; |
| 125 // Playback timestamp was updated. |
| 126 bool timestamp_updated_; |
114 | 127 |
115 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); | 128 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); |
116 }; | 129 }; |
117 | 130 |
118 class MockDemuxerAndroid : public DemuxerAndroid { | 131 class MockDemuxerAndroid : public DemuxerAndroid { |
119 public: | 132 public: |
120 explicit MockDemuxerAndroid(base::MessageLoop* message_loop) | 133 explicit MockDemuxerAndroid(base::MessageLoop* message_loop) |
121 : message_loop_(message_loop), | 134 : message_loop_(message_loop), |
122 num_data_requests_(0), | 135 num_data_requests_(0), |
123 num_seek_requests_(0), | 136 num_seek_requests_(0), |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 demuxer_->num_data_requests()); | 345 demuxer_->num_data_requests()); |
333 | 346 |
334 // Verify player has decoder job iff the config included the media type for | 347 // Verify player has decoder job iff the config included the media type for |
335 // the job and the player is expected to request data due to Start(), above. | 348 // the job and the player is expected to request data due to Start(), above. |
336 EXPECT_EQ(expect_player_requests_data && has_audio, | 349 EXPECT_EQ(expect_player_requests_data && has_audio, |
337 GetMediaDecoderJob(true) != NULL); | 350 GetMediaDecoderJob(true) != NULL); |
338 EXPECT_EQ(expect_player_requests_data && has_video, | 351 EXPECT_EQ(expect_player_requests_data && has_video, |
339 GetMediaDecoderJob(false) != NULL); | 352 GetMediaDecoderJob(false) != NULL); |
340 } | 353 } |
341 | 354 |
| 355 // Keeps decoding audio data until the decoder starts to output samples. |
| 356 // Gives up if no audio output after decoding 10 frames. |
| 357 void DecodeAudioDataUntilOutputBecomesAvailable() { |
| 358 EXPECT_TRUE(player_.IsPlaying()); |
| 359 base::TimeDelta current_time = player_.GetCurrentTime(); |
| 360 base::TimeDelta start_timestamp = current_time; |
| 361 for (int i = 0; i < 10; ++i) { |
| 362 manager_.ResetTimestampUpdated(); |
| 363 player_.OnDemuxerDataAvailable( |
| 364 CreateReadFromDemuxerAckForAudio(i > 3 ? 3 : i)); |
| 365 WaitForAudioDecodeDone(); |
| 366 base::TimeDelta new_current_time = player_.GetCurrentTime(); |
| 367 EXPECT_LE(current_time.InMilliseconds(), |
| 368 new_current_time.InMilliseconds()); |
| 369 current_time = new_current_time; |
| 370 if (manager_.timestamp_updated()) { |
| 371 EXPECT_LT(start_timestamp.InMillisecondsF(), |
| 372 new_current_time.InMillisecondsF()); |
| 373 return; |
| 374 } |
| 375 } |
| 376 EXPECT_TRUE(false); |
| 377 } |
| 378 |
342 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { | 379 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { |
343 AccessUnit unit; | 380 AccessUnit unit; |
344 | 381 |
345 unit.status = DemuxerStream::kOk; | 382 unit.status = DemuxerStream::kOk; |
346 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile( | 383 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile( |
347 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id) | 384 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id) |
348 : "vp8-I-frame-320x240"); | 385 : "vp8-I-frame-320x240"); |
349 unit.data = std::vector<uint8>( | 386 unit.data = std::vector<uint8>( |
350 buffer->data(), buffer->data() + buffer->data_size()); | 387 buffer->data(), buffer->data() + buffer->data_size()); |
351 | 388 |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 // No seeks should have occurred. | 1107 // No seeks should have occurred. |
1071 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1108 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
1072 } | 1109 } |
1073 | 1110 |
1074 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { | 1111 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { |
1075 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1112 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
1076 | 1113 |
1077 // Test start time ticks will reset after decoder job underruns. | 1114 // Test start time ticks will reset after decoder job underruns. |
1078 StartAudioDecoderJob(true); | 1115 StartAudioDecoderJob(true); |
1079 | 1116 |
1080 // For the first couple chunks, the decoder job may return | 1117 DecodeAudioDataUntilOutputBecomesAvailable(); |
1081 // DECODE_FORMAT_CHANGED status instead of DECODE_SUCCEEDED status. Decode | |
1082 // more frames to guarantee that DECODE_SUCCEEDED will be returned. | |
1083 for (int i = 0; i < 4; ++i) { | |
1084 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i)); | |
1085 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
1086 // Decode data until decoder started requesting new data again. | |
1087 WaitForAudioDecodeDone(); | |
1088 } | |
1089 | 1118 |
1090 // The decoder job should finish and a new request will be sent. | 1119 // The decoder job should finish and a new request will be sent. |
1091 EXPECT_EQ(5, demuxer_->num_data_requests()); | |
1092 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
1093 base::TimeTicks previous = StartTimeTicks(); | 1120 base::TimeTicks previous = StartTimeTicks(); |
| 1121 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
1094 | 1122 |
1095 // Let the decoder starve. | 1123 // Let the decoder starve. |
1096 TriggerPlayerStarvation(); | 1124 TriggerPlayerStarvation(); |
1097 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | |
1098 WaitForAudioDecodeDone(); | 1125 WaitForAudioDecodeDone(); |
1099 | 1126 |
1100 // Verify the start time ticks is cleared at this point because the | 1127 // Verify the start time ticks is cleared at this point because the |
1101 // player is prefetching. | 1128 // player is prefetching. |
1102 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); | 1129 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); |
1103 | 1130 |
1104 // Send new data to the decoder so it can finish prefetching. This should | 1131 // Send new data to the decoder so it can finish prefetching. This should |
1105 // reset the start time ticks. | 1132 // reset the start time ticks. |
1106 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | 1133 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
1107 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); | 1134 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { | 1492 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { |
1466 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1493 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
1467 | 1494 |
1468 // Test decoder job will begin prerolling upon seek, when it was not | 1495 // Test decoder job will begin prerolling upon seek, when it was not |
1469 // prerolling prior to the seek. | 1496 // prerolling prior to the seek. |
1470 StartAudioDecoderJob(true); | 1497 StartAudioDecoderJob(true); |
1471 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); | 1498 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); |
1472 EXPECT_TRUE(IsPrerolling(true)); | 1499 EXPECT_TRUE(IsPrerolling(true)); |
1473 | 1500 |
1474 // Complete the initial preroll by feeding data to the decoder. | 1501 // Complete the initial preroll by feeding data to the decoder. |
1475 for (int i = 0; i < 4; ++i) { | 1502 DecodeAudioDataUntilOutputBecomesAvailable(); |
1476 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i)); | |
1477 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
1478 WaitForAudioDecodeDone(); | |
1479 } | |
1480 EXPECT_LT(0.0, player_.GetCurrentTime().InMillisecondsF()); | |
1481 EXPECT_FALSE(IsPrerolling(true)); | 1503 EXPECT_FALSE(IsPrerolling(true)); |
1482 | 1504 |
1483 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); | 1505 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); |
1484 | 1506 |
1485 // Prerolling should have begun again. | 1507 // Prerolling should have begun again. |
1486 EXPECT_TRUE(IsPrerolling(true)); | 1508 EXPECT_TRUE(IsPrerolling(true)); |
1487 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF()); | 1509 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF()); |
1488 | 1510 |
1489 // Send data at and after the seek position. Prerolling should complete. | 1511 // Send data at and after the seek position. Prerolling should complete. |
1490 for (int i = 0; i < 4; ++i) { | 1512 for (int i = 0; i < 4; ++i) { |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 // player has not yet received media crypto. | 2082 // player has not yet received media crypto. |
2061 DemuxerConfigs configs = CreateVideoDemuxerConfigs(); | 2083 DemuxerConfigs configs = CreateVideoDemuxerConfigs(); |
2062 configs.is_video_encrypted = true; | 2084 configs.is_video_encrypted = true; |
2063 | 2085 |
2064 player_.OnDemuxerConfigsAvailable(configs); | 2086 player_.OnDemuxerConfigsAvailable(configs); |
2065 CreateNextTextureAndSetVideoSurface(); | 2087 CreateNextTextureAndSetVideoSurface(); |
2066 EXPECT_FALSE(IsPendingSurfaceChange()); | 2088 EXPECT_FALSE(IsPendingSurfaceChange()); |
2067 EXPECT_FALSE(GetMediaDecoderJob(false)); | 2089 EXPECT_FALSE(GetMediaDecoderJob(false)); |
2068 } | 2090 } |
2069 | 2091 |
| 2092 TEST_F(MediaSourcePlayerTest, CurrentTimeUpdatedWhileDecoderStarved) { |
| 2093 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 2094 |
| 2095 // Test that current time is updated while decoder is starved. |
| 2096 StartAudioDecoderJob(true); |
| 2097 DecodeAudioDataUntilOutputBecomesAvailable(); |
| 2098 |
| 2099 // Trigger starvation while the decoder is decoding. |
| 2100 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
| 2101 manager_.ResetTimestampUpdated(); |
| 2102 TriggerPlayerStarvation(); |
| 2103 WaitForAudioDecodeDone(); |
| 2104 |
| 2105 // Current time should be updated. |
| 2106 EXPECT_TRUE(manager_.timestamp_updated()); |
| 2107 } |
| 2108 |
| 2109 TEST_F(MediaSourcePlayerTest, CurrentTimeKeepsIncreasingAfterConfigChange) { |
| 2110 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 2111 |
| 2112 // Test current time keep on increasing after audio config change. |
| 2113 // Test that current time is updated while decoder is starved. |
| 2114 StartAudioDecoderJob(true); |
| 2115 |
| 2116 DecodeAudioDataUntilOutputBecomesAvailable(); |
| 2117 |
| 2118 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0); |
| 2119 player_.OnDemuxerDataAvailable(data); |
| 2120 WaitForAudioDecodeDone(); |
| 2121 |
| 2122 // Simulate arrival of new configs. |
| 2123 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis)); |
| 2124 DecodeAudioDataUntilOutputBecomesAvailable(); |
| 2125 } |
| 2126 |
2070 } // namespace media | 2127 } // namespace media |
OLD | NEW |