| Index: media/base/android/media_codec_player_unittest.cc
|
| diff --git a/media/base/android/media_codec_player_unittest.cc b/media/base/android/media_codec_player_unittest.cc
|
| index f8b35f355e5c00febad0041912ac716d2660f020..afc7702f185f0bbf39e4d5f0287a3e632b4df343 100644
|
| --- a/media/base/android/media_codec_player_unittest.cc
|
| +++ b/media/base/android/media_codec_player_unittest.cc
|
| @@ -237,7 +237,7 @@ class MockDemuxerAndroid : public DemuxerAndroid {
|
| // DemuxerAndroid implementation
|
| void Initialize(DemuxerAndroidClient* client) override;
|
| void RequestDemuxerData(DemuxerStream::Type type) override;
|
| - void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
|
| + void RequestDemuxerSeek(const base::TimeDelta& seek_request,
|
| bool is_browser_seek) override;
|
|
|
| // Sets the audio data factory.
|
| @@ -250,6 +250,16 @@ class MockDemuxerAndroid : public DemuxerAndroid {
|
| video_factory_ = factory.Pass();
|
| }
|
|
|
| + // Set the preroll interval after seek for audio stream.
|
| + void SetAudioPrerollInterval(base::TimeDelta value) {
|
| + audio_preroll_interval_ = value;
|
| + }
|
| +
|
| + // Set the preroll interval after seek for video stream.
|
| + void SetVideoPrerollInterval(base::TimeDelta value) {
|
| + video_preroll_interval_ = value;
|
| + }
|
| +
|
| // Sets the delay in OnDemuxerSeekDone response.
|
| void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; }
|
|
|
| @@ -270,6 +280,8 @@ class MockDemuxerAndroid : public DemuxerAndroid {
|
| scoped_ptr<DemuxerConfigs> pending_configs_;
|
| scoped_ptr<AudioFactory> audio_factory_;
|
| scoped_ptr<VideoFactory> video_factory_;
|
| + base::TimeDelta audio_preroll_interval_;
|
| + base::TimeDelta video_preroll_interval_;
|
| base::TimeDelta seek_done_delay_;
|
| int num_seeks_;
|
| int num_browser_seeks_;
|
| @@ -309,12 +321,17 @@ void MockDemuxerAndroid::RequestDemuxerData(DemuxerStream::Type type) {
|
| delay);
|
| }
|
|
|
| -void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
|
| +void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& seek_request,
|
| bool is_browser_seek) {
|
| // Tell data factories to start next chunk with the new timestamp.
|
| - if (audio_factory_)
|
| + if (audio_factory_) {
|
| + base::TimeDelta time_to_seek =
|
| + std::max(base::TimeDelta(), seek_request - audio_preroll_interval_);
|
| audio_factory_->SeekTo(time_to_seek);
|
| + }
|
| if (video_factory_) {
|
| + base::TimeDelta time_to_seek =
|
| + std::max(base::TimeDelta(), seek_request - video_preroll_interval_);
|
| video_factory_->SeekTo(time_to_seek);
|
| video_factory_->RequestKeyFrame();
|
| }
|
| @@ -326,7 +343,7 @@ void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
|
| // Post OnDemuxerSeekDone() to the player.
|
| DCHECK(client_);
|
| base::TimeDelta reported_seek_time =
|
| - is_browser_seek ? time_to_seek : kNoTimestamp();
|
| + is_browser_seek ? seek_request : kNoTimestamp();
|
| GetMediaTaskRunner()->PostDelayedTask(
|
| FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
|
| base::Unretained(client_), reported_seek_time),
|
| @@ -1055,4 +1072,55 @@ TEST_F(MediaCodecPlayerTest, VideoReleaseWhileWaitingForSeek) {
|
| &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
|
| }
|
|
|
| +TEST_F(MediaCodecPlayerTest, VideoPrerollAfterSeek) {
|
| + SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
|
| +
|
| + // A simple test for preroll for video stream only. After the seek is done
|
| + // the data factory generates the frames with pts before the seek time, and
|
| + // they should not be rendered. We deduce which frame is rendered by looking
|
| + // at the reported time progress.
|
| +
|
| + base::TimeDelta duration = base::TimeDelta::FromMilliseconds(600);
|
| + base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500);
|
| + base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
|
| +
|
| + // Tell demuxer to make the first frame 100ms earlier than the seek request.
|
| + demuxer_->SetVideoPrerollInterval(base::TimeDelta::FromMilliseconds(100));
|
| +
|
| + demuxer_->SetVideoFactory(
|
| + scoped_ptr<VideoFactory>(new VideoFactory(duration)));
|
| +
|
| + CreatePlayer();
|
| + SetVideoSurface();
|
| +
|
| + // Wait till the player is initialized on media thread.
|
| + EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
|
| + base::Unretained(demuxer_))));
|
| +
|
| + // Post configuration after the player has been initialized.
|
| + demuxer_->PostInternalConfigs();
|
| +
|
| + // Issue SeekTo().
|
| + player_->SeekTo(seek_position);
|
| +
|
| + // Start the playback and make sure it is started.
|
| + player_->Start();
|
| +
|
| + EXPECT_TRUE(
|
| + WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
|
| + base::Unretained(&manager_)),
|
| + start_timeout));
|
| +
|
| + // Wait for completion.
|
| + EXPECT_TRUE(
|
| + WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
|
| + base::Unretained(&manager_))));
|
| +
|
| + // The first pts should be equal than seek position even if video frames
|
| + // started 100 ms eralier than the seek request.
|
| + EXPECT_EQ(seek_position, manager_.pts_stat_.min());
|
| +
|
| + EXPECT_EQ(6, manager_.pts_stat_.num_values());
|
| +}
|
| +
|
| } // namespace media
|
|
|