Index: media/base/android/media_source_player_unittest.cc |
diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc |
index 9c6a0627d1184dce97f620e96a59465a5cb0f697..fb51118571f6b24441cf2c2b9b8ca747b84a9bdf 100644 |
--- a/media/base/android/media_source_player_unittest.cc |
+++ b/media/base/android/media_source_player_unittest.cc |
@@ -339,6 +339,23 @@ class MediaSourcePlayerTest : public testing::Test { |
GetMediaDecoderJob(false) != NULL); |
} |
+ // Keeps decoding audio data until the AudioTrack's buffer is full and the |
+ // system starts to render the decoded audio. |
+ // Gives up if no audio is rendered after decoding 10 frames. |
+ void DecodeAudioDataUntilAudioBufferBecomesFull() { |
+ EXPECT_TRUE(player_.IsPlaying()); |
+ base::TimeDelta start_timestamp = player_.GetCurrentTime(); |
+ int i; |
+ for (i = 0; i < 10; ++i) { |
+ player_.OnDemuxerDataAvailable( |
+ CreateReadFromDemuxerAckForAudio(i > 3 ? 3 : i)); |
+ WaitForAudioDecodeDone(); |
+ if ((player_.GetCurrentTime() - start_timestamp).InMilliseconds() > 0) |
wolenetz
2014/04/15 22:17:34
nit: Please add a check to ensure player current t
qinmin
2014/04/15 22:43:42
Done.
|
+ return; |
+ } |
+ EXPECT_TRUE(false); |
+ } |
+ |
AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { |
AccessUnit unit; |
@@ -1077,24 +1094,14 @@ TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { |
// Test start time ticks will reset after decoder job underruns. |
StartAudioDecoderJob(true); |
- // For the first couple chunks, the decoder job may return |
- // DECODE_FORMAT_CHANGED status instead of DECODE_SUCCEEDED status. Decode |
- // more frames to guarantee that DECODE_SUCCEEDED will be returned. |
- for (int i = 0; i < 4; ++i) { |
- player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i)); |
- EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
- // Decode data until decoder started requesting new data again. |
- WaitForAudioDecodeDone(); |
- } |
+ DecodeAudioDataUntilAudioBufferBecomesFull(); |
// The decoder job should finish and a new request will be sent. |
- EXPECT_EQ(5, demuxer_->num_data_requests()); |
- EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
base::TimeTicks previous = StartTimeTicks(); |
+ player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
wolenetz
2014/04/15 22:17:34
Curiousity nit: Must we feed more data prior to tr
qinmin
2014/04/15 22:43:42
The issue is that when AudioTrack's buffer become
wolenetz
2014/04/15 23:48:58
Hmm. Starvation could come from two directions:
On
qinmin
2014/04/16 01:48:24
In the new code:
A. if DecodeAudioDataUntilAudioBu
|
// Let the decoder starve. |
TriggerPlayerStarvation(); |
- player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
WaitForAudioDecodeDone(); |
// Verify the start time ticks is cleared at this point because the |
@@ -1472,12 +1479,7 @@ TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { |
EXPECT_TRUE(IsPrerolling(true)); |
// Complete the initial preroll by feeding data to the decoder. |
- for (int i = 0; i < 4; ++i) { |
- player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i)); |
- EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
- WaitForAudioDecodeDone(); |
- } |
- EXPECT_LT(0.0, player_.GetCurrentTime().InMillisecondsF()); |
+ DecodeAudioDataUntilAudioBufferBecomesFull(); |
EXPECT_FALSE(IsPrerolling(true)); |
SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); |
@@ -2067,4 +2069,48 @@ TEST_F(MediaSourcePlayerTest, SurfaceChangeClearedEvenIfMediaCryptoAbsent) { |
EXPECT_FALSE(GetMediaDecoderJob(false)); |
} |
+TEST_F(MediaSourcePlayerTest, CurrentTimeUpdatedWhileDecoderStarved) { |
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
+ |
+ // Test that current time is updated while decoder is starved. |
+ StartAudioDecoderJob(true); |
+ DecodeAudioDataUntilAudioBufferBecomesFull(); |
+ base::TimeDelta current_time = player_.GetCurrentTime(); |
+ |
+ // Trigger starvation while the decoder is decoding. |
+ player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
+ TriggerPlayerStarvation(); |
+ WaitForAudioDecodeDone(); |
+ |
+ // Current time should be updated. |
+ EXPECT_LT(current_time.InMillisecondsF(), |
+ player_.GetCurrentTime().InMillisecondsF()); |
+} |
+ |
+TEST_F(MediaSourcePlayerTest, CurrentTimeKeepsIncreasingAfterConfigChange) { |
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
+ |
+ // Test current time keep on increasing after audio config change. |
+ // Test that current time is updated while decoder is starved. |
+ StartAudioDecoderJob(true); |
+ |
+ DecodeAudioDataUntilAudioBufferBecomesFull(); |
+ base::TimeDelta current_time = player_.GetCurrentTime(); |
+ |
+ DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0); |
+ player_.OnDemuxerDataAvailable(data); |
+ WaitForAudioDecodeDone(); |
+ |
+ // Simulate arrival of new configs. |
+ player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis)); |
+ for (int i = 0; i < 4; ++i) { |
wolenetz
2014/04/15 22:17:34
nit: DecodeAudioDataUntilAudioBufferBecomesFull()
qinmin
2014/04/15 22:43:42
Done.
|
+ player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i)); |
+ WaitForAudioDecodeDone(); |
+ base::TimeDelta new_current_time = player_.GetCurrentTime(); |
+ EXPECT_LE(current_time.InMillisecondsF(), |
+ new_current_time.InMillisecondsF()); |
+ current_time = new_current_time; |
+ } |
+} |
+ |
} // namespace media |