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 for (int i = 0; i < 10; ++i) { | |
361 manager_.ResetTimestampUpdated(); | |
362 player_.OnDemuxerDataAvailable( | |
363 CreateReadFromDemuxerAckForAudio(i > 3 ? 3 : i)); | |
364 WaitForAudioDecodeDone(); | |
365 base::TimeDelta new_current_time = player_.GetCurrentTime(); | |
366 EXPECT_LE(current_time.InMilliseconds(), | |
367 new_current_time.InMilliseconds()); | |
368 current_time = new_current_time; | |
369 if (manager_.timestamp_updated()) | |
wolenetz
2014/04/17 21:35:28
Please also include the time delta check here. Onl
qinmin
2014/04/17 23:03:35
Done.
| |
370 return; | |
371 } | |
372 EXPECT_TRUE(false); | |
373 } | |
374 | |
342 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { | 375 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { |
343 AccessUnit unit; | 376 AccessUnit unit; |
344 | 377 |
345 unit.status = DemuxerStream::kOk; | 378 unit.status = DemuxerStream::kOk; |
346 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile( | 379 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile( |
347 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id) | 380 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id) |
348 : "vp8-I-frame-320x240"); | 381 : "vp8-I-frame-320x240"); |
349 unit.data = std::vector<uint8>( | 382 unit.data = std::vector<uint8>( |
350 buffer->data(), buffer->data() + buffer->data_size()); | 383 buffer->data(), buffer->data() + buffer->data_size()); |
351 | 384 |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1070 // No seeks should have occurred. | 1103 // No seeks should have occurred. |
1071 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1104 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
1072 } | 1105 } |
1073 | 1106 |
1074 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { | 1107 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { |
1075 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1108 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
1076 | 1109 |
1077 // Test start time ticks will reset after decoder job underruns. | 1110 // Test start time ticks will reset after decoder job underruns. |
1078 StartAudioDecoderJob(true); | 1111 StartAudioDecoderJob(true); |
1079 | 1112 |
1080 // For the first couple chunks, the decoder job may return | 1113 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 | 1114 |
1090 // The decoder job should finish and a new request will be sent. | 1115 // 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(); | 1116 base::TimeTicks previous = StartTimeTicks(); |
1117 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | |
1094 | 1118 |
1095 // Let the decoder starve. | 1119 // Let the decoder starve. |
1096 TriggerPlayerStarvation(); | 1120 TriggerPlayerStarvation(); |
1097 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | |
1098 WaitForAudioDecodeDone(); | 1121 WaitForAudioDecodeDone(); |
1099 | 1122 |
1100 // Verify the start time ticks is cleared at this point because the | 1123 // Verify the start time ticks is cleared at this point because the |
1101 // player is prefetching. | 1124 // player is prefetching. |
1102 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); | 1125 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); |
1103 | 1126 |
1104 // Send new data to the decoder so it can finish prefetching. This should | 1127 // Send new data to the decoder so it can finish prefetching. This should |
1105 // reset the start time ticks. | 1128 // reset the start time ticks. |
1106 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | 1129 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
1107 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); | 1130 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1465 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { | 1488 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { |
1466 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1489 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
1467 | 1490 |
1468 // Test decoder job will begin prerolling upon seek, when it was not | 1491 // Test decoder job will begin prerolling upon seek, when it was not |
1469 // prerolling prior to the seek. | 1492 // prerolling prior to the seek. |
1470 StartAudioDecoderJob(true); | 1493 StartAudioDecoderJob(true); |
1471 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); | 1494 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); |
1472 EXPECT_TRUE(IsPrerolling(true)); | 1495 EXPECT_TRUE(IsPrerolling(true)); |
1473 | 1496 |
1474 // Complete the initial preroll by feeding data to the decoder. | 1497 // Complete the initial preroll by feeding data to the decoder. |
1475 for (int i = 0; i < 4; ++i) { | 1498 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)); | 1499 EXPECT_FALSE(IsPrerolling(true)); |
1482 | 1500 |
1483 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); | 1501 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); |
1484 | 1502 |
1485 // Prerolling should have begun again. | 1503 // Prerolling should have begun again. |
1486 EXPECT_TRUE(IsPrerolling(true)); | 1504 EXPECT_TRUE(IsPrerolling(true)); |
1487 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF()); | 1505 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF()); |
1488 | 1506 |
1489 // Send data at and after the seek position. Prerolling should complete. | 1507 // Send data at and after the seek position. Prerolling should complete. |
1490 for (int i = 0; i < 4; ++i) { | 1508 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. | 2078 // player has not yet received media crypto. |
2061 DemuxerConfigs configs = CreateVideoDemuxerConfigs(); | 2079 DemuxerConfigs configs = CreateVideoDemuxerConfigs(); |
2062 configs.is_video_encrypted = true; | 2080 configs.is_video_encrypted = true; |
2063 | 2081 |
2064 player_.OnDemuxerConfigsAvailable(configs); | 2082 player_.OnDemuxerConfigsAvailable(configs); |
2065 CreateNextTextureAndSetVideoSurface(); | 2083 CreateNextTextureAndSetVideoSurface(); |
2066 EXPECT_FALSE(IsPendingSurfaceChange()); | 2084 EXPECT_FALSE(IsPendingSurfaceChange()); |
2067 EXPECT_FALSE(GetMediaDecoderJob(false)); | 2085 EXPECT_FALSE(GetMediaDecoderJob(false)); |
2068 } | 2086 } |
2069 | 2087 |
2088 TEST_F(MediaSourcePlayerTest, CurrentTimeUpdatedWhileDecoderStarved) { | |
2089 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
2090 | |
2091 // Test that current time is updated while decoder is starved. | |
2092 StartAudioDecoderJob(true); | |
2093 DecodeAudioDataUntilOutputBecomesAvailable(); | |
2094 | |
2095 // Trigger starvation while the decoder is decoding. | |
2096 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | |
2097 manager_.ResetTimestampUpdated(); | |
2098 TriggerPlayerStarvation(); | |
2099 WaitForAudioDecodeDone(); | |
2100 | |
2101 // Current time should be updated. | |
2102 EXPECT_TRUE(manager_.timestamp_updated()); | |
2103 } | |
2104 | |
2105 TEST_F(MediaSourcePlayerTest, CurrentTimeKeepsIncreasingAfterConfigChange) { | |
2106 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
2107 | |
2108 // Test current time keep on increasing after audio config change. | |
2109 // Test that current time is updated while decoder is starved. | |
2110 StartAudioDecoderJob(true); | |
2111 | |
2112 DecodeAudioDataUntilOutputBecomesAvailable(); | |
2113 | |
2114 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0); | |
2115 player_.OnDemuxerDataAvailable(data); | |
2116 WaitForAudioDecodeDone(); | |
2117 | |
2118 // Simulate arrival of new configs. | |
2119 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis)); | |
2120 DecodeAudioDataUntilOutputBecomesAvailable(); | |
2121 } | |
2122 | |
2070 } // namespace media | 2123 } // namespace media |
OLD | NEW |