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

Side by Side Diff: media/base/android/media_source_player_unittest.cc

Issue 239363003: Fix an issue that audio and video may ran out of sync (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressing comments Created 6 years, 8 months 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
« no previous file with comments | « media/base/android/media_source_player.cc ('k') | media/base/android/video_decoder_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 demuxer_->num_data_requests()); 332 demuxer_->num_data_requests());
333 333
334 // Verify player has decoder job iff the config included the media type for 334 // 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. 335 // the job and the player is expected to request data due to Start(), above.
336 EXPECT_EQ(expect_player_requests_data && has_audio, 336 EXPECT_EQ(expect_player_requests_data && has_audio,
337 GetMediaDecoderJob(true) != NULL); 337 GetMediaDecoderJob(true) != NULL);
338 EXPECT_EQ(expect_player_requests_data && has_video, 338 EXPECT_EQ(expect_player_requests_data && has_video,
339 GetMediaDecoderJob(false) != NULL); 339 GetMediaDecoderJob(false) != NULL);
340 } 340 }
341 341
342 // Keeps decoding audio data until the AudioTrack's buffer is full and the
343 // system starts to render the decoded audio.
344 // Gives up if no audio is rendered after decoding 10 frames.
345 void DecodeAudioDataUntilAudioBufferBecomesFull() {
346 EXPECT_TRUE(player_.IsPlaying());
347 base::TimeDelta start_timestamp = player_.GetCurrentTime();
348 int i;
349 for (i = 0; i < 10; ++i) {
350 player_.OnDemuxerDataAvailable(
351 CreateReadFromDemuxerAckForAudio(i > 3 ? 3 : i));
352 WaitForAudioDecodeDone();
353 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.
354 return;
355 }
356 EXPECT_TRUE(false);
357 }
358
342 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { 359 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) {
343 AccessUnit unit; 360 AccessUnit unit;
344 361
345 unit.status = DemuxerStream::kOk; 362 unit.status = DemuxerStream::kOk;
346 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile( 363 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
347 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id) 364 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id)
348 : "vp8-I-frame-320x240"); 365 : "vp8-I-frame-320x240");
349 unit.data = std::vector<uint8>( 366 unit.data = std::vector<uint8>(
350 buffer->data(), buffer->data() + buffer->data_size()); 367 buffer->data(), buffer->data() + buffer->data_size());
351 368
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // No seeks should have occurred. 1087 // No seeks should have occurred.
1071 EXPECT_EQ(0, demuxer_->num_seek_requests()); 1088 EXPECT_EQ(0, demuxer_->num_seek_requests());
1072 } 1089 }
1073 1090
1074 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) { 1091 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) {
1075 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1092 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1076 1093
1077 // Test start time ticks will reset after decoder job underruns. 1094 // Test start time ticks will reset after decoder job underruns.
1078 StartAudioDecoderJob(true); 1095 StartAudioDecoderJob(true);
1079 1096
1080 // For the first couple chunks, the decoder job may return 1097 DecodeAudioDataUntilAudioBufferBecomesFull();
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 1098
1090 // The decoder job should finish and a new request will be sent. 1099 // 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(); 1100 base::TimeTicks previous = StartTimeTicks();
1101 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
1094 1102
1095 // Let the decoder starve. 1103 // Let the decoder starve.
1096 TriggerPlayerStarvation(); 1104 TriggerPlayerStarvation();
1097 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1098 WaitForAudioDecodeDone(); 1105 WaitForAudioDecodeDone();
1099 1106
1100 // Verify the start time ticks is cleared at this point because the 1107 // Verify the start time ticks is cleared at this point because the
1101 // player is prefetching. 1108 // player is prefetching.
1102 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); 1109 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks());
1103 1110
1104 // Send new data to the decoder so it can finish prefetching. This should 1111 // Send new data to the decoder so it can finish prefetching. This should
1105 // reset the start time ticks. 1112 // reset the start time ticks.
1106 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); 1113 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1107 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); 1114 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { 1472 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) {
1466 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1473 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1467 1474
1468 // Test decoder job will begin prerolling upon seek, when it was not 1475 // Test decoder job will begin prerolling upon seek, when it was not
1469 // prerolling prior to the seek. 1476 // prerolling prior to the seek.
1470 StartAudioDecoderJob(true); 1477 StartAudioDecoderJob(true);
1471 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); 1478 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1472 EXPECT_TRUE(IsPrerolling(true)); 1479 EXPECT_TRUE(IsPrerolling(true));
1473 1480
1474 // Complete the initial preroll by feeding data to the decoder. 1481 // Complete the initial preroll by feeding data to the decoder.
1475 for (int i = 0; i < 4; ++i) { 1482 DecodeAudioDataUntilAudioBufferBecomesFull();
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)); 1483 EXPECT_FALSE(IsPrerolling(true));
1482 1484
1483 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500)); 1485 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1484 1486
1485 // Prerolling should have begun again. 1487 // Prerolling should have begun again.
1486 EXPECT_TRUE(IsPrerolling(true)); 1488 EXPECT_TRUE(IsPrerolling(true));
1487 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF()); 1489 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1488 1490
1489 // Send data at and after the seek position. Prerolling should complete. 1491 // Send data at and after the seek position. Prerolling should complete.
1490 for (int i = 0; i < 4; ++i) { 1492 for (int i = 0; i < 4; ++i) {
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 // player has not yet received media crypto. 2062 // player has not yet received media crypto.
2061 DemuxerConfigs configs = CreateVideoDemuxerConfigs(); 2063 DemuxerConfigs configs = CreateVideoDemuxerConfigs();
2062 configs.is_video_encrypted = true; 2064 configs.is_video_encrypted = true;
2063 2065
2064 player_.OnDemuxerConfigsAvailable(configs); 2066 player_.OnDemuxerConfigsAvailable(configs);
2065 CreateNextTextureAndSetVideoSurface(); 2067 CreateNextTextureAndSetVideoSurface();
2066 EXPECT_FALSE(IsPendingSurfaceChange()); 2068 EXPECT_FALSE(IsPendingSurfaceChange());
2067 EXPECT_FALSE(GetMediaDecoderJob(false)); 2069 EXPECT_FALSE(GetMediaDecoderJob(false));
2068 } 2070 }
2069 2071
2072 TEST_F(MediaSourcePlayerTest, CurrentTimeUpdatedWhileDecoderStarved) {
2073 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2074
2075 // Test that current time is updated while decoder is starved.
2076 StartAudioDecoderJob(true);
2077 DecodeAudioDataUntilAudioBufferBecomesFull();
2078 base::TimeDelta current_time = player_.GetCurrentTime();
2079
2080 // Trigger starvation while the decoder is decoding.
2081 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
2082 TriggerPlayerStarvation();
2083 WaitForAudioDecodeDone();
2084
2085 // Current time should be updated.
2086 EXPECT_LT(current_time.InMillisecondsF(),
2087 player_.GetCurrentTime().InMillisecondsF());
2088 }
2089
2090 TEST_F(MediaSourcePlayerTest, CurrentTimeKeepsIncreasingAfterConfigChange) {
2091 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2092
2093 // Test current time keep on increasing after audio config change.
2094 // Test that current time is updated while decoder is starved.
2095 StartAudioDecoderJob(true);
2096
2097 DecodeAudioDataUntilAudioBufferBecomesFull();
2098 base::TimeDelta current_time = player_.GetCurrentTime();
2099
2100 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0);
2101 player_.OnDemuxerDataAvailable(data);
2102 WaitForAudioDecodeDone();
2103
2104 // Simulate arrival of new configs.
2105 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
2106 for (int i = 0; i < 4; ++i) {
wolenetz 2014/04/15 22:17:34 nit: DecodeAudioDataUntilAudioBufferBecomesFull()
qinmin 2014/04/15 22:43:42 Done.
2107 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
2108 WaitForAudioDecodeDone();
2109 base::TimeDelta new_current_time = player_.GetCurrentTime();
2110 EXPECT_LE(current_time.InMillisecondsF(),
2111 new_current_time.InMillisecondsF());
2112 current_time = new_current_time;
2113 }
2114 }
2115
2070 } // namespace media 2116 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.cc ('k') | media/base/android/video_decoder_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698