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

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

Issue 596093002: Let audio wait for video to finish prerolling after seek (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressing comments Created 6 years, 2 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
« no previous file with comments | « media/base/android/media_source_player.cc ('k') | no next file » | 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 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests()); 472 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
473 player_.OnDemuxerSeekDone(kNoTimestamp()); 473 player_.OnDemuxerSeekDone(kNoTimestamp());
474 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests()); 474 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests());
475 475
476 // No other seek should have been requested. 476 // No other seek should have been requested.
477 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests()); 477 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
478 } 478 }
479 479
480 // Preroll the decoder job to |target_timestamp|. The first access unit 480 // Preroll the decoder job to |target_timestamp|. The first access unit
481 // to decode will have a timestamp equal to |start_timestamp|. 481 // to decode will have a timestamp equal to |start_timestamp|.
482 // |is_clock_manager| indicates whether the decoder serves as the clock
483 // manager for the player.
482 // TODO(qinmin): Add additional test cases for out-of-order decodes. 484 // TODO(qinmin): Add additional test cases for out-of-order decodes.
483 // See http://crbug.com/331421. 485 // See http://crbug.com/331421.
484 void PrerollDecoderToTime(bool is_audio, 486 void PrerollDecoderToTime(bool is_audio,
485 const base::TimeDelta& start_timestamp, 487 const base::TimeDelta& start_timestamp,
486 const base::TimeDelta& target_timestamp) { 488 const base::TimeDelta& target_timestamp,
487 EXPECT_EQ(target_timestamp, player_.GetCurrentTime()); 489 bool is_clock_manager) {
490 // For streams with both audio and video, it is possible that audio rolls
491 // past the |target_timestamp|. As a result, the current time may be larger
492 // than the |target_timestamp| for video as it may not be the clock manager.
493 EXPECT_TRUE(!is_clock_manager ||
494 target_timestamp == player_.GetCurrentTime());
488 // |start_timestamp| must be smaller than |target_timestamp|. 495 // |start_timestamp| must be smaller than |target_timestamp|.
489 EXPECT_LE(start_timestamp, target_timestamp); 496 EXPECT_LE(start_timestamp, target_timestamp);
490 DemuxerData data = is_audio ? CreateReadFromDemuxerAckForAudio(1) : 497 DemuxerData data = is_audio ? CreateReadFromDemuxerAckForAudio(1) :
491 CreateReadFromDemuxerAckForVideo(); 498 CreateReadFromDemuxerAckForVideo();
492 int current_timestamp = start_timestamp.InMilliseconds(); 499 int current_timestamp = start_timestamp.InMilliseconds();
493 500
494 // Send some data with access unit timestamps before the |target_timestamp|, 501 // Send some data with access unit timestamps before the |target_timestamp|,
495 // and continue sending the data until preroll finishes. 502 // and continue sending the data until preroll finishes.
496 // This simulates the common condition that AUs received after browser 503 // This simulates the common condition that AUs received after browser
497 // seek begin with timestamps before the seek target, and don't 504 // seek begin with timestamps before the seek target, and don't
498 // immediately complete preroll. 505 // immediately complete preroll.
499 while (IsPrerolling(is_audio)) { 506 while (IsPrerolling(is_audio)) {
500 data.access_units[0].timestamp = 507 data.access_units[0].timestamp =
501 base::TimeDelta::FromMilliseconds(current_timestamp); 508 base::TimeDelta::FromMilliseconds(current_timestamp);
502 player_.OnDemuxerDataAvailable(data); 509 player_.OnDemuxerDataAvailable(data);
503 EXPECT_TRUE(GetMediaDecoderJob(is_audio)->is_decoding()); 510 EXPECT_TRUE(GetMediaDecoderJob(is_audio)->is_decoding());
504 EXPECT_TRUE(GetMediaCodecBridge(is_audio)); 511 EXPECT_TRUE(GetMediaCodecBridge(is_audio));
505 EXPECT_EQ(target_timestamp, player_.GetCurrentTime()); 512 EXPECT_TRUE(!is_clock_manager ||
513 target_timestamp == player_.GetCurrentTime());
506 current_timestamp += 30; 514 current_timestamp += 30;
507 WaitForDecodeDone(is_audio, !is_audio); 515 WaitForDecodeDone(is_audio, !is_audio);
508 } 516 }
509 EXPECT_LE(target_timestamp, player_.GetCurrentTime()); 517 EXPECT_LE(target_timestamp, player_.GetCurrentTime());
510 } 518 }
511 519
512 DemuxerData CreateReadFromDemuxerAckWithConfigChanged( 520 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(
513 bool is_audio, 521 bool is_audio,
514 int config_unit_index, 522 int config_unit_index,
515 const DemuxerConfigs& configs) { 523 const DemuxerConfigs& configs) {
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 1517
1510 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) { 1518 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
1511 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1519 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1512 1520
1513 // Test decoder job will preroll the media to the seek position. 1521 // Test decoder job will preroll the media to the seek position.
1514 StartAudioDecoderJob(); 1522 StartAudioDecoderJob();
1515 1523
1516 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100)); 1524 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1517 EXPECT_TRUE(IsPrerolling(true)); 1525 EXPECT_TRUE(IsPrerolling(true));
1518 PrerollDecoderToTime( 1526 PrerollDecoderToTime(
1519 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100)); 1527 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1520 } 1528 }
1521 1529
1522 TEST_F(MediaSourcePlayerTest, PrerollVideoAfterSeek) { 1530 TEST_F(MediaSourcePlayerTest, PrerollVideoAfterSeek) {
1523 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1531 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1524 1532
1525 // Test decoder job will preroll the media to the seek position. 1533 // Test decoder job will preroll the media to the seek position.
1526 CreateNextTextureAndSetVideoSurface(); 1534 CreateNextTextureAndSetVideoSurface();
1527 StartVideoDecoderJob(); 1535 StartVideoDecoderJob();
1528 1536
1529 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100)); 1537 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1530 EXPECT_TRUE(IsPrerolling(false)); 1538 EXPECT_TRUE(IsPrerolling(false));
1531 PrerollDecoderToTime( 1539 PrerollDecoderToTime(
1532 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100)); 1540 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1533 } 1541 }
1534 1542
1535 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) { 1543 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) {
1536 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1544 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1537 1545
1538 // Test decoder job will begin prerolling upon seek, when it was not 1546 // Test decoder job will begin prerolling upon seek, when it was not
1539 // prerolling prior to the seek. 1547 // prerolling prior to the seek.
1540 StartAudioDecoderJob(); 1548 StartAudioDecoderJob();
1541 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true); 1549 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1542 EXPECT_TRUE(IsPrerolling(true)); 1550 EXPECT_TRUE(IsPrerolling(true));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 player_.OnDemuxerDataAvailable(data); 1608 player_.OnDemuxerDataAvailable(data);
1601 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); 1609 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1602 WaitForAudioDecodeDone(); 1610 WaitForAudioDecodeDone();
1603 } 1611 }
1604 EXPECT_TRUE(IsPrerolling(true)); 1612 EXPECT_TRUE(IsPrerolling(true));
1605 } 1613 }
1606 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF()); 1614 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1607 EXPECT_TRUE(IsPrerolling(true)); 1615 EXPECT_TRUE(IsPrerolling(true));
1608 1616
1609 // Send data after the seek position. 1617 // Send data after the seek position.
1610 PrerollDecoderToTime(true, target_timestamp, target_timestamp); 1618 PrerollDecoderToTime(true, target_timestamp, target_timestamp, true);
1611 } 1619 }
1612 1620
1613 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossConfigChange) { 1621 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossConfigChange) {
1614 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1622 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1615 1623
1616 // Test decoder job will resume media prerolling if interrupted by 1624 // Test decoder job will resume media prerolling if interrupted by
1617 // |kConfigChanged| and OnDemuxerConfigsAvailable(). 1625 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1618 StartAudioDecoderJob(); 1626 StartAudioDecoderJob();
1619 1627
1620 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100)); 1628 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1621 EXPECT_TRUE(IsPrerolling(true)); 1629 EXPECT_TRUE(IsPrerolling(true));
1622 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); 1630 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1623 1631
1624 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true); 1632 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
1625 1633
1626 // In response to data request, simulate that demuxer signals config change by 1634 // In response to data request, simulate that demuxer signals config change by
1627 // sending an AU with |kConfigChanged|. 1635 // sending an AU with |kConfigChanged|.
1628 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged( 1636 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
1629 true, 0, configs); 1637 true, 0, configs);
1630 player_.OnDemuxerDataAvailable(data); 1638 player_.OnDemuxerDataAvailable(data);
1639
1631 PrerollDecoderToTime( 1640 PrerollDecoderToTime(
1632 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100)); 1641 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1633 } 1642 }
1634 1643
1635 TEST_F(MediaSourcePlayerTest, PrerollContinuesAfterUnchangedConfigs) { 1644 TEST_F(MediaSourcePlayerTest, PrerollContinuesAfterUnchangedConfigs) {
1636 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1645 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1637 1646
1638 // Test decoder job will resume media prerolling if interrupted by a config 1647 // Test decoder job will resume media prerolling if interrupted by a config
1639 // change access unit with unchanged configs. 1648 // change access unit with unchanged configs.
1640 StartAudioDecoderJob(); 1649 StartAudioDecoderJob();
1641 1650
1642 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100)); 1651 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1643 EXPECT_TRUE(IsPrerolling(true)); 1652 EXPECT_TRUE(IsPrerolling(true));
1644 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); 1653 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1645 1654
1646 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false); 1655 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false);
1647 1656
1648 // In response to data request, simulate that demuxer signals config change by 1657 // In response to data request, simulate that demuxer signals config change by
1649 // sending an AU with |kConfigChanged|. 1658 // sending an AU with |kConfigChanged|.
1650 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged( 1659 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
1651 true, 0, configs); 1660 true, 0, configs);
1652 player_.OnDemuxerDataAvailable(data); 1661 player_.OnDemuxerDataAvailable(data);
1653 PrerollDecoderToTime( 1662 PrerollDecoderToTime(
1654 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100)); 1663 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1664 }
1665
1666 TEST_F(MediaSourcePlayerTest, AudioPrerollFinishesBeforeVideo) {
1667 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1668
1669 // Test that after audio finishes prerolling, it will wait for video to finish
1670 // prerolling before advancing together.
1671 CreateNextTextureAndSetVideoSurface();
1672 Start(CreateAudioVideoDemuxerConfigs());
1673
1674 // Initiate a seek.
1675 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(100);
1676 player_.SeekTo(seek_position);
1677 player_.OnDemuxerDataAvailable(CreateAbortedAck(true));
1678 player_.OnDemuxerDataAvailable(CreateAbortedAck(false));
1679 WaitForDecodeDone(true, true);
1680
1681 // Verify that the seek is requested.
1682 EXPECT_EQ(1, demuxer_->num_seek_requests());
1683 player_.OnDemuxerSeekDone(kNoTimestamp());
1684 EXPECT_EQ(4, demuxer_->num_data_requests());
1685 EXPECT_EQ(player_.GetCurrentTime().InMillisecondsF(), 100.0);
1686 EXPECT_EQ(GetPrerollTimestamp().InMillisecondsF(), 100.0);
1687
1688 // Send both audio and video data to finish prefetching.
1689 base::TimeDelta seek_ack_position = base::TimeDelta::FromMilliseconds(70);
1690 DemuxerData audio_data = CreateReadFromDemuxerAckForAudio(0);
1691 audio_data.access_units[0].timestamp = seek_ack_position;
1692 DemuxerData video_data = CreateReadFromDemuxerAckForVideo();
1693 video_data.access_units[0].timestamp = seek_ack_position;
1694 player_.OnDemuxerDataAvailable(audio_data);
1695 player_.OnDemuxerDataAvailable(video_data);
1696 WaitForAudioDecodeDone();
1697 WaitForVideoDecodeDone();
1698
1699 // Send audio data at and after the seek position. Audio should finish
1700 // prerolling and stop decoding.
1701 EXPECT_EQ(6, demuxer_->num_data_requests());
1702 PrerollDecoderToTime(true, seek_position, seek_position, true);
1703 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1704 EXPECT_FALSE(IsPrerolling(true));
1705 EXPECT_TRUE(IsPrerolling(false));
1706
1707 // Send video data to let video finish prerolling.
1708 PrerollDecoderToTime(false, seek_position, seek_position, false);
1709 EXPECT_FALSE(IsPrerolling(false));
1710
1711 // Both audio and video decoders should start decoding again.
1712 player_.OnDemuxerDataAvailable(audio_data);
1713 player_.OnDemuxerDataAvailable(video_data);
1714 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1715 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1655 } 1716 }
1656 1717
1657 TEST_F(MediaSourcePlayerTest, SimultaneousAudioVideoConfigChange) { 1718 TEST_F(MediaSourcePlayerTest, SimultaneousAudioVideoConfigChange) {
1658 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1719 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1659 1720
1660 // Test that the player allows simultaneous audio and video config change, 1721 // Test that the player allows simultaneous audio and video config change,
1661 // such as might occur during OnPrefetchDone() if next access unit for both 1722 // such as might occur during OnPrefetchDone() if next access unit for both
1662 // audio and video jobs is |kConfigChanged|. 1723 // audio and video jobs is |kConfigChanged|.
1663 CreateNextTextureAndSetVideoSurface(); 1724 CreateNextTextureAndSetVideoSurface();
1664 Start(CreateAudioVideoDemuxerConfigs()); 1725 Start(CreateAudioVideoDemuxerConfigs());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 // Simulate browser seek is done, but to a later time than was requested. 1831 // Simulate browser seek is done, but to a later time than was requested.
1771 EXPECT_LT(player_.GetCurrentTime().InMillisecondsF(), 100); 1832 EXPECT_LT(player_.GetCurrentTime().InMillisecondsF(), 100);
1772 player_.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100)); 1833 player_.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1773 // Because next AU is not I-frame, MediaCodecBridge will not be recreated. 1834 // Because next AU is not I-frame, MediaCodecBridge will not be recreated.
1774 EXPECT_FALSE(GetMediaCodecBridge(false)); 1835 EXPECT_FALSE(GetMediaCodecBridge(false));
1775 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF()); 1836 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1776 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); 1837 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1777 EXPECT_EQ(3, demuxer_->num_data_requests()); 1838 EXPECT_EQ(3, demuxer_->num_data_requests());
1778 1839
1779 PrerollDecoderToTime( 1840 PrerollDecoderToTime(
1780 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100)); 1841 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1781 } 1842 }
1782 1843
1783 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChange) { 1844 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChange) {
1784 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 1845 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1785 1846
1786 // Test that video config change notification results in creating a new 1847 // Test that video config change notification results in creating a new
1787 // video codec without any browser seek. 1848 // video codec without any browser seek.
1788 StartConfigChange(false, true, 1, false); 1849 StartConfigChange(false, true, 1, false);
1789 1850
1790 // New video codec should have been created and configured, without any 1851 // New video codec should have been created and configured, without any
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 2252
2192 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true); 2253 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
2193 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged( 2254 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
2194 true, 0, configs); 2255 true, 0, configs);
2195 player_.OnDemuxerDataAvailable(data); 2256 player_.OnDemuxerDataAvailable(data);
2196 WaitForAudioDecodeDone(); 2257 WaitForAudioDecodeDone();
2197 DecodeAudioDataUntilOutputBecomesAvailable(); 2258 DecodeAudioDataUntilOutputBecomesAvailable();
2198 } 2259 }
2199 2260
2200 } // namespace media 2261 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698