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

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

Issue 1254293003: MediaCodecPlayer implementation (stage 4 - preroll) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-browserseek
Patch Set: Rebased Created 5 years, 4 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/timer/timer.h" 7 #include "base/timer/timer.h"
8 #include "media/base/android/demuxer_android.h" 8 #include "media/base/android/demuxer_android.h"
9 #include "media/base/android/media_codec_bridge.h" 9 #include "media/base/android/media_codec_bridge.h"
10 #include "media/base/android/media_codec_player.h" 10 #include "media/base/android/media_codec_player.h"
(...skipping 30 matching lines...) Expand all
41 const base::TimeDelta kDefaultTimeout = base::TimeDelta::FromMilliseconds(200); 41 const base::TimeDelta kDefaultTimeout = base::TimeDelta::FromMilliseconds(200);
42 const base::TimeDelta kAudioFramePeriod = 42 const base::TimeDelta kAudioFramePeriod =
43 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz 43 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz
44 const base::TimeDelta kVideoFramePeriod = base::TimeDelta::FromMilliseconds(20); 44 const base::TimeDelta kVideoFramePeriod = base::TimeDelta::FromMilliseconds(20);
45 45
46 // The predicate that always returns false, used for WaitForDelay implementation 46 // The predicate that always returns false, used for WaitForDelay implementation
47 bool AlwaysFalse() { 47 bool AlwaysFalse() {
48 return false; 48 return false;
49 } 49 }
50 50
51 // The method used to compare two TimeDelta values in expectations. 51 // The method used to compare two time values of type T in expectations.
52 bool AlmostEqual(base::TimeDelta a, base::TimeDelta b, double tolerance_ms) { 52 // Type T requires that a difference of type base::TimeDelta is defined.
53 template <typename T>
54 bool AlmostEqual(T a, T b, double tolerance_ms) {
53 return (a - b).magnitude().InMilliseconds() <= tolerance_ms; 55 return (a - b).magnitude().InMilliseconds() <= tolerance_ms;
54 } 56 }
55 57
56 // Mock of MediaPlayerManager for testing purpose. 58 // Mock of MediaPlayerManager for testing purpose.
57 59
58 class MockMediaPlayerManager : public MediaPlayerManager { 60 class MockMediaPlayerManager : public MediaPlayerManager {
59 public: 61 public:
60 MockMediaPlayerManager() 62 MockMediaPlayerManager()
61 : playback_completed_(false), 63 : playback_completed_(false),
62 num_seeks_completed_(0), 64 num_seeks_completed_(0),
63 weak_ptr_factory_(this) {} 65 weak_ptr_factory_(this) {}
64 ~MockMediaPlayerManager() override {} 66 ~MockMediaPlayerManager() override {}
65 67
66 MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; } 68 MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; }
67 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return nullptr; } 69 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return nullptr; }
68 70
71 // Regular time update callback, reports current playback time to
72 // MediaPlayerManager.
69 void OnTimeUpdate(int player_id, 73 void OnTimeUpdate(int player_id,
70 base::TimeDelta current_timestamp, 74 base::TimeDelta current_timestamp,
71 base::TimeTicks current_time_ticks) override { 75 base::TimeTicks current_time_ticks) override {
72 pts_stat_.AddValue(current_timestamp); 76 pts_stat_.AddValue(current_timestamp);
73 } 77 }
74 78
75 void OnMediaMetadataChanged(int player_id, 79 void OnMediaMetadataChanged(int player_id,
76 base::TimeDelta duration, 80 base::TimeDelta duration,
77 int width, 81 int width,
78 int height, 82 int height,
(...skipping 17 matching lines...) Expand all
96 void OnError(int player_id, int error) override {} 100 void OnError(int player_id, int error) override {}
97 void OnVideoSizeChanged(int player_id, int width, int height) override {} 101 void OnVideoSizeChanged(int player_id, int width, int height) override {}
98 void OnAudibleStateChanged(int player_id, bool is_audible_now) override {} 102 void OnAudibleStateChanged(int player_id, bool is_audible_now) override {}
99 void OnWaitingForDecryptionKey(int player_id) override {} 103 void OnWaitingForDecryptionKey(int player_id) override {}
100 MediaPlayerAndroid* GetFullscreenPlayer() override { return nullptr; } 104 MediaPlayerAndroid* GetFullscreenPlayer() override { return nullptr; }
101 MediaPlayerAndroid* GetPlayer(int player_id) override { return nullptr; } 105 MediaPlayerAndroid* GetPlayer(int player_id) override { return nullptr; }
102 bool RequestPlay(int player_id) override { return true; } 106 bool RequestPlay(int player_id) override { return true; }
103 107
104 void OnMediaResourcesRequested(int player_id) {} 108 void OnMediaResourcesRequested(int player_id) {}
105 109
110 // Time update callback that reports the internal progress of the stream.
111 // Implementation dependent, used for testing only.
112 void OnDecodersTimeUpdate(DemuxerStream::Type stream_type,
113 base::TimeDelta now_playing,
114 base::TimeDelta last_buffered) {
115 PTSTime& hit = first_frame_hit_[stream_type];
116 if (hit.is_null())
117 hit = PTSTime(now_playing, base::TimeTicks::Now());
118 }
119
120 // First frame information
121 base::TimeDelta FirstFramePTS(DemuxerStream::Type stream_type) const {
122 return first_frame_hit_[stream_type].pts;
123 }
124 base::TimeTicks FirstFrameTime(DemuxerStream::Type stream_type) const {
125 return first_frame_hit_[stream_type].time;
126 }
127
106 base::WeakPtr<MockMediaPlayerManager> GetWeakPtr() { 128 base::WeakPtr<MockMediaPlayerManager> GetWeakPtr() {
107 return weak_ptr_factory_.GetWeakPtr(); 129 return weak_ptr_factory_.GetWeakPtr();
108 } 130 }
109 131
110 // Conditions to wait for. 132 // Conditions to wait for.
111 bool IsMetadataChanged() const { return media_metadata_.modified; } 133 bool IsMetadataChanged() const { return media_metadata_.modified; }
112 bool IsPlaybackCompleted() const { return playback_completed_; } 134 bool IsPlaybackCompleted() const { return playback_completed_; }
113 bool IsPlaybackStarted() const { return pts_stat_.num_values() > 0; } 135 bool IsPlaybackStarted() const { return pts_stat_.num_values() > 0; }
114 bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const { 136 bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const {
115 return pts_stat_.max() > pts; 137 return pts_stat_.max() > pts;
116 } 138 }
117 bool IsSeekCompleted() const { return num_seeks_completed_ > 0; } 139 bool IsSeekCompleted() const { return num_seeks_completed_ > 0; }
140 bool HasFirstFrame(DemuxerStream::Type stream_type) const {
141 return !first_frame_hit_[stream_type].is_null();
142 }
118 143
119 struct MediaMetadata { 144 struct MediaMetadata {
120 base::TimeDelta duration; 145 base::TimeDelta duration;
121 int width; 146 int width;
122 int height; 147 int height;
123 bool modified; 148 bool modified;
124 MediaMetadata() : width(0), height(0), modified(false) {} 149 MediaMetadata() : width(0), height(0), modified(false) {}
125 }; 150 };
126 MediaMetadata media_metadata_; 151 MediaMetadata media_metadata_;
127 152
128 Minimax<base::TimeDelta> pts_stat_; 153 Minimax<base::TimeDelta> pts_stat_;
129 154
130 private: 155 private:
131 bool playback_completed_; 156 bool playback_completed_;
132 int num_seeks_completed_; 157 int num_seeks_completed_;
133 158
159 struct PTSTime {
160 base::TimeDelta pts;
161 base::TimeTicks time;
162 PTSTime() : pts(), time() {}
163 PTSTime(base::TimeDelta p, base::TimeTicks t) : pts(p), time(t) {}
164 bool is_null() const { return time.is_null(); }
165 };
166 PTSTime first_frame_hit_[DemuxerStream::NUM_TYPES];
167
134 base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_; 168 base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_;
135 169
136 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); 170 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
137 }; 171 };
138 172
139 // Helper method that creates demuxer configuration. 173 // Helper method that creates demuxer configuration.
140 174
141 DemuxerConfigs CreateAudioVideoConfigs(const base::TimeDelta& duration, 175 DemuxerConfigs CreateAudioVideoConfigs(const base::TimeDelta& duration,
142 const gfx::Size& video_size) { 176 const gfx::Size& video_size) {
143 DemuxerConfigs configs = 177 DemuxerConfigs configs =
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 264
231 class MockDemuxerAndroid : public DemuxerAndroid { 265 class MockDemuxerAndroid : public DemuxerAndroid {
232 public: 266 public:
233 MockDemuxerAndroid() 267 MockDemuxerAndroid()
234 : client_(nullptr), num_seeks_(0), num_browser_seeks_(0) {} 268 : client_(nullptr), num_seeks_(0), num_browser_seeks_(0) {}
235 ~MockDemuxerAndroid() override {} 269 ~MockDemuxerAndroid() override {}
236 270
237 // DemuxerAndroid implementation 271 // DemuxerAndroid implementation
238 void Initialize(DemuxerAndroidClient* client) override; 272 void Initialize(DemuxerAndroidClient* client) override;
239 void RequestDemuxerData(DemuxerStream::Type type) override; 273 void RequestDemuxerData(DemuxerStream::Type type) override;
240 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 274 void RequestDemuxerSeek(const base::TimeDelta& seek_request,
241 bool is_browser_seek) override; 275 bool is_browser_seek) override;
242 276
243 // Sets the audio data factory. 277 // Sets the audio data factory.
244 void SetAudioFactory(scoped_ptr<AudioFactory> factory) { 278 void SetAudioFactory(scoped_ptr<AudioFactory> factory) {
245 audio_factory_ = factory.Pass(); 279 audio_factory_ = factory.Pass();
246 } 280 }
247 281
248 // Sets the video data factory. 282 // Sets the video data factory.
249 void SetVideoFactory(scoped_ptr<VideoFactory> factory) { 283 void SetVideoFactory(scoped_ptr<VideoFactory> factory) {
250 video_factory_ = factory.Pass(); 284 video_factory_ = factory.Pass();
251 } 285 }
252 286
287 // Accessors for data factories.
288 AudioFactory* audio_factory() const { return audio_factory_.get(); }
289 VideoFactory* video_factory() const { return video_factory_.get(); }
290
291 // Set the preroll interval after seek for audio stream.
292 void SetAudioPrerollInterval(base::TimeDelta value) {
293 audio_preroll_interval_ = value;
294 }
295
296 // Set the preroll interval after seek for video stream.
297 void SetVideoPrerollInterval(base::TimeDelta value) {
298 video_preroll_interval_ = value;
299 }
300
253 // Sets the delay in OnDemuxerSeekDone response. 301 // Sets the delay in OnDemuxerSeekDone response.
254 void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; } 302 void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; }
255 303
256 // Post DemuxerConfigs to the client (i.e. the player) on correct thread. 304 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
257 void PostConfigs(const DemuxerConfigs& configs); 305 void PostConfigs(const DemuxerConfigs& configs);
258 306
259 // Post DemuxerConfigs derived from data factories that has been set. 307 // Post DemuxerConfigs derived from data factories that has been set.
260 void PostInternalConfigs(); 308 void PostInternalConfigs();
261 309
262 // Conditions to wait for. 310 // Conditions to wait for.
263 bool IsInitialized() const { return client_; } 311 bool IsInitialized() const { return client_; }
264 bool HasPendingConfigs() const { return pending_configs_; } 312 bool HasPendingConfigs() const { return pending_configs_; }
265 bool ReceivedSeekRequest() const { return num_seeks_ > 0; } 313 bool ReceivedSeekRequest() const { return num_seeks_ > 0; }
266 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; } 314 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
267 315
268 private: 316 private:
269 DemuxerAndroidClient* client_; 317 DemuxerAndroidClient* client_;
270 scoped_ptr<DemuxerConfigs> pending_configs_; 318 scoped_ptr<DemuxerConfigs> pending_configs_;
271 scoped_ptr<AudioFactory> audio_factory_; 319 scoped_ptr<AudioFactory> audio_factory_;
272 scoped_ptr<VideoFactory> video_factory_; 320 scoped_ptr<VideoFactory> video_factory_;
321 base::TimeDelta audio_preroll_interval_;
322 base::TimeDelta video_preroll_interval_;
273 base::TimeDelta seek_done_delay_; 323 base::TimeDelta seek_done_delay_;
274 int num_seeks_; 324 int num_seeks_;
275 int num_browser_seeks_; 325 int num_browser_seeks_;
276 326
277 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); 327 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
278 }; 328 };
279 329
280 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) { 330 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) {
281 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__; 331 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
282 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 332 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
(...skipping 19 matching lines...) Expand all
302 chunk.type = type; 352 chunk.type = type;
303 353
304 // Post to Media thread. 354 // Post to Media thread.
305 DCHECK(client_); 355 DCHECK(client_);
306 GetMediaTaskRunner()->PostDelayedTask( 356 GetMediaTaskRunner()->PostDelayedTask(
307 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable, 357 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable,
308 base::Unretained(client_), chunk), 358 base::Unretained(client_), chunk),
309 delay); 359 delay);
310 } 360 }
311 361
312 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 362 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& seek_request,
313 bool is_browser_seek) { 363 bool is_browser_seek) {
314 // Tell data factories to start next chunk with the new timestamp. 364 // Tell data factories to start next chunk with the new timestamp.
315 if (audio_factory_) 365 if (audio_factory_) {
366 base::TimeDelta time_to_seek =
367 std::max(base::TimeDelta(), seek_request - audio_preroll_interval_);
316 audio_factory_->SeekTo(time_to_seek); 368 audio_factory_->SeekTo(time_to_seek);
369 }
317 if (video_factory_) { 370 if (video_factory_) {
371 base::TimeDelta time_to_seek =
372 std::max(base::TimeDelta(), seek_request - video_preroll_interval_);
318 video_factory_->SeekTo(time_to_seek); 373 video_factory_->SeekTo(time_to_seek);
319 video_factory_->RequestKeyFrame(); 374 video_factory_->RequestKeyFrame();
320 } 375 }
321 376
322 ++num_seeks_; 377 ++num_seeks_;
323 if (is_browser_seek) 378 if (is_browser_seek)
324 ++num_browser_seeks_; 379 ++num_browser_seeks_;
325 380
326 // Post OnDemuxerSeekDone() to the player. 381 // Post OnDemuxerSeekDone() to the player.
327 DCHECK(client_); 382 DCHECK(client_);
328 base::TimeDelta reported_seek_time = 383 base::TimeDelta reported_seek_time =
329 is_browser_seek ? time_to_seek : kNoTimestamp(); 384 is_browser_seek ? seek_request : kNoTimestamp();
330 GetMediaTaskRunner()->PostDelayedTask( 385 GetMediaTaskRunner()->PostDelayedTask(
331 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone, 386 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
332 base::Unretained(client_), reported_seek_time), 387 base::Unretained(client_), reported_seek_time),
333 seek_done_delay_); 388 seek_done_delay_);
334 } 389 }
335 390
336 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) { 391 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) {
337 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid, PostConfigs, configs); 392 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid, PostConfigs, configs);
338 393
339 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__; 394 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // reaches the given value or for timeout to expire. Returns true if the 446 // reaches the given value or for timeout to expire. Returns true if the
392 // playback has passed the given position. 447 // playback has passed the given position.
393 bool WaitForPlaybackBeyondPosition( 448 bool WaitForPlaybackBeyondPosition(
394 const base::TimeDelta& pts, 449 const base::TimeDelta& pts,
395 const base::TimeDelta& timeout = kDefaultTimeout); 450 const base::TimeDelta& timeout = kDefaultTimeout);
396 451
397 // Helper method that starts video only stream. Waits till it actually 452 // Helper method that starts video only stream. Waits till it actually
398 // started. 453 // started.
399 void StartVideoPlayback(base::TimeDelta duration); 454 void StartVideoPlayback(base::TimeDelta duration);
400 455
456 // Helper method that starts audio and video streams with preroll.
457 // The preroll is achieved by setting significant video preroll interval
458 // so video will have to catch up with audio. To make room for this interval
459 // the Start() command is preceded by SeekTo().
460 void StartAVSeekAndPreroll(base::TimeDelta duration,
461 base::TimeDelta seek_position,
462 base::TimeDelta video_preroll);
463
401 base::MessageLoop message_loop_; 464 base::MessageLoop message_loop_;
402 MockMediaPlayerManager manager_; 465 MockMediaPlayerManager manager_;
403 MockDemuxerAndroid* demuxer_; // owned by player_ 466 MockDemuxerAndroid* demuxer_; // owned by player_
404 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_; 467 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
405 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_; 468 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
406 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread() 469 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread()
407 470
408 private: 471 private:
409 bool is_timeout_expired() const { return is_timeout_expired_; } 472 bool is_timeout_expired() const { return is_timeout_expired_; }
410 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; } 473 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 EXPECT_FALSE(manager_.IsPlaybackStarted()); 576 EXPECT_FALSE(manager_.IsPlaybackStarted());
514 player_->Start(); 577 player_->Start();
515 578
516 // Wait for playback to start. 579 // Wait for playback to start.
517 EXPECT_TRUE( 580 EXPECT_TRUE(
518 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted, 581 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
519 base::Unretained(&manager_)), 582 base::Unretained(&manager_)),
520 start_timeout)); 583 start_timeout));
521 } 584 }
522 585
586 void MediaCodecPlayerTest::StartAVSeekAndPreroll(
587 base::TimeDelta duration,
588 base::TimeDelta seek_position,
589 base::TimeDelta video_preroll) {
590 const base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
591
592 demuxer_->SetVideoPrerollInterval(video_preroll);
593
594 demuxer_->SetAudioFactory(
595 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
596 demuxer_->SetVideoFactory(
597 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
598
599 CreatePlayer();
600 SetVideoSurface();
601
602 // Set special testing callback to receive PTS from decoders.
603 player_->SetDecodersTimeCallbackForTests(
604 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate,
605 base::Unretained(&manager_)));
606
607 // Wait till the player is initialized on media thread.
608 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
609 base::Unretained(demuxer_))));
610
611 // Post configuration after the player has been initialized.
612 demuxer_->PostInternalConfigs();
613
614 // Issue SeekTo().
615 player_->SeekTo(seek_position);
616
617 // Start the playback.
618 player_->Start();
619
620 // Wait till preroll starts.
621 EXPECT_TRUE(WaitForCondition(
622 base::Bind(&MediaCodecPlayer::IsPrerollingForTests,
623 base::Unretained(player_), DemuxerStream::VIDEO),
624 start_timeout));
625 }
626
523 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) { 627 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) {
524 // Post configuration when there is no player yet. 628 // Post configuration when there is no player yet.
525 EXPECT_EQ(nullptr, player_); 629 EXPECT_EQ(nullptr, player_);
526 630
527 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); 631 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
528 632
529 demuxer_->PostConfigs( 633 demuxer_->PostConfigs(
530 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration)); 634 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration));
531 635
532 // Wait until the configuration gets to the media thread. 636 // Wait until the configuration gets to the media thread.
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 reconfigure_timeout)); 1155 reconfigure_timeout));
1052 1156
1053 // Timestamps should start at the new seek position 1157 // Timestamps should start at the new seek position
1054 EXPECT_LE(seek_position, manager_.pts_stat_.min()); 1158 EXPECT_LE(seek_position, manager_.pts_stat_.min());
1055 1159
1056 // The player should have reported the seek completion to the manager. 1160 // The player should have reported the seek completion to the manager.
1057 EXPECT_TRUE(WaitForCondition(base::Bind( 1161 EXPECT_TRUE(WaitForCondition(base::Bind(
1058 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_)))); 1162 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
1059 } 1163 }
1060 1164
1165 TEST_F(MediaCodecPlayerTest, VideoPrerollAfterSeek) {
1166 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1167
1168 // A simple test for preroll for video stream only. After the seek is done
1169 // the data factory generates the frames with pts before the seek time, and
1170 // they should not be rendered. We deduce which frame is rendered by looking
1171 // at the reported time progress.
1172
1173 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(600);
1174 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500);
1175 base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
1176
1177 // Tell demuxer to make the first frame 100ms earlier than the seek request.
1178 demuxer_->SetVideoPrerollInterval(base::TimeDelta::FromMilliseconds(100));
1179
1180 demuxer_->SetVideoFactory(
1181 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
1182
1183 CreatePlayer();
1184 SetVideoSurface();
1185
1186 // Wait till the player is initialized on media thread.
1187 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
1188 base::Unretained(demuxer_))));
1189
1190 // Post configuration after the player has been initialized.
1191 demuxer_->PostInternalConfigs();
1192
1193 // Issue SeekTo().
1194 player_->SeekTo(seek_position);
1195
1196 // Start the playback and make sure it is started.
1197 player_->Start();
1198
1199 EXPECT_TRUE(
1200 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1201 base::Unretained(&manager_)),
1202 start_timeout));
1203
1204 // Wait for completion.
1205 EXPECT_TRUE(
1206 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
1207 base::Unretained(&manager_))));
1208
1209 // The first pts should be equal than seek position even if video frames
1210 // started 100 ms eralier than the seek request.
1211 EXPECT_EQ(seek_position, manager_.pts_stat_.min());
1212
1213 EXPECT_EQ(6, manager_.pts_stat_.num_values());
1214 }
1215
1216 TEST_F(MediaCodecPlayerTest, AVPrerollAudioWaitsForVideo) {
1217 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1218
1219 // Test that during prerolling neither audio nor video plays and that both
1220 // resume simultaneously after preroll is finished. In other words, test
1221 // that preroll works.
1222 // We put the video into the long preroll and intercept the time when first
1223 // rendering happens in each stream. The moment of rendering is approximated
1224 // with a decoder PTS that is delivered by a test-only callback.
1225
1226 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
1227
1228 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1229 // per frame it would take 250 ms to preroll.
1230 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1231 base::TimeDelta preroll_intvl = base::TimeDelta::FromMilliseconds(500);
1232 base::TimeDelta preroll_timeout = base::TimeDelta::FromMilliseconds(1000);
1233
1234 StartAVSeekAndPreroll(duration, seek_position, preroll_intvl);
1235
1236 // Wait till preroll finishes and the real playback starts.
1237 EXPECT_TRUE(
1238 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1239 base::Unretained(&manager_)),
1240 preroll_timeout));
1241
1242 // Ensure that the first audio and video pts are close to each other and are
1243 // reported at the close moments in time.
1244
1245 EXPECT_TRUE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1246 EXPECT_TRUE(WaitForCondition(
1247 base::Bind(&MockMediaPlayerManager::HasFirstFrame,
1248 base::Unretained(&manager_), DemuxerStream::VIDEO)));
1249
1250 EXPECT_TRUE(AlmostEqual(manager_.FirstFramePTS(DemuxerStream::AUDIO),
1251 manager_.FirstFramePTS(DemuxerStream::VIDEO), 10));
1252
1253 EXPECT_TRUE(AlmostEqual(manager_.FirstFrameTime(DemuxerStream::AUDIO),
1254 manager_.FirstFrameTime(DemuxerStream::VIDEO), 50));
1255
1256 // The playback should start at |seek_position|
1257 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
1258 }
1259
1260 TEST_F(MediaCodecPlayerTest, AVPrerollReleaseAndRestart) {
1261 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1262
1263 // Test that player will resume prerolling if prerolling is interrupted by
1264 // Release() and Start().
1265
1266 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
1267
1268 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1269 // per frame it would take 250 ms to preroll.
1270 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1271 base::TimeDelta preroll_intvl = base::TimeDelta::FromMilliseconds(500);
1272
1273 base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
1274 base::TimeDelta preroll_timeout = base::TimeDelta::FromMilliseconds(1000);
1275
1276 StartAVSeekAndPreroll(duration, seek_position, preroll_intvl);
1277
1278 // Issue Release().
1279 player_->Release();
1280
1281 // Make sure we have not been playing.
1282 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1283
1284 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1285 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::VIDEO));
1286
1287 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::AUDIO));
1288 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::VIDEO));
1289 EXPECT_EQ(0, manager_.pts_stat_.num_values());
1290
1291 // Restart. Release() removed the video surface, we need to set it again.
1292 SetVideoSurface();
1293 player_->Start();
1294
1295 // The playback should pass through prerolling phase.
1296 EXPECT_TRUE(WaitForCondition(
1297 base::Bind(&MediaCodecPlayer::IsPrerollingForTests,
1298 base::Unretained(player_), DemuxerStream::VIDEO),
1299 start_timeout));
1300
1301 // Wait till preroll finishes and the real playback starts.
1302 EXPECT_TRUE(
1303 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1304 base::Unretained(&manager_)),
1305 preroll_timeout));
1306
1307 // Ensure that the first audio and video pts are close to each other and are
1308 // reported at the close moments in time.
1309
1310 EXPECT_TRUE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1311 EXPECT_TRUE(WaitForCondition(
1312 base::Bind(&MockMediaPlayerManager::HasFirstFrame,
1313 base::Unretained(&manager_), DemuxerStream::VIDEO)));
1314
1315 EXPECT_TRUE(AlmostEqual(manager_.FirstFramePTS(DemuxerStream::AUDIO),
1316 manager_.FirstFramePTS(DemuxerStream::VIDEO), 10));
1317
1318 EXPECT_TRUE(AlmostEqual(manager_.FirstFrameTime(DemuxerStream::AUDIO),
1319 manager_.FirstFrameTime(DemuxerStream::VIDEO), 50));
1320
1321 // The playback should start at |seek_position|
1322 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
1323 }
1324
1325 TEST_F(MediaCodecPlayerTest, AVPrerollStopAndRestart) {
1326 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1327
1328 // Test that if Pause() happens during the preroll phase,
1329 // we continue to do preroll after restart.
1330
1331 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1200);
1332
1333 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1334 // per frame it would take 250 ms to preroll.
1335 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1336 base::TimeDelta preroll_intvl = base::TimeDelta::FromMilliseconds(500);
1337
1338 base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
1339 base::TimeDelta preroll_timeout = base::TimeDelta::FromMilliseconds(1000);
1340
1341 StartAVSeekAndPreroll(duration, seek_position, preroll_intvl);
1342
1343 // Video stream should be prerolling. Request to stop.
1344 EXPECT_FALSE(IsPaused());
1345 player_->Pause(true);
1346
1347 EXPECT_TRUE(WaitForCondition(
1348 base::Bind(&MediaCodecPlayerTest::IsPaused, base::Unretained(this))));
1349
1350 // Test that we have not been playing.
1351 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1352 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::VIDEO));
1353
1354 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::AUDIO));
1355 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::VIDEO));
1356 EXPECT_EQ(0, manager_.pts_stat_.num_values());
1357
1358 // Restart.
1359 player_->Start();
1360
1361 // There should be preroll after the start.
1362 EXPECT_TRUE(WaitForCondition(
1363 base::Bind(&MediaCodecPlayer::IsPrerollingForTests,
1364 base::Unretained(player_), DemuxerStream::VIDEO),
1365 start_timeout));
1366
1367 // Wait for a short period of time, so that preroll is still ongoing,
1368 // and pause again.
1369 WaitForDelay(base::TimeDelta::FromMilliseconds(100));
1370
1371 EXPECT_FALSE(IsPaused());
1372 player_->Pause(true);
1373
1374 EXPECT_TRUE(WaitForCondition(
1375 base::Bind(&MediaCodecPlayerTest::IsPaused, base::Unretained(this))));
1376
1377 // Check that we still haven't started rendering.
1378 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1379 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::VIDEO));
1380
1381 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::AUDIO));
1382 EXPECT_FALSE(player_->IsPrerollingForTests(DemuxerStream::VIDEO));
1383 EXPECT_EQ(0, manager_.pts_stat_.num_values());
1384
1385 // Restart again.
1386 player_->Start();
1387
1388 // Wait till we start to play.
1389 EXPECT_TRUE(
1390 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1391 base::Unretained(&manager_)),
1392 preroll_timeout));
1393
1394 // Check that we did prerolling, i.e. audio did wait for video.
1395 EXPECT_TRUE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1396 EXPECT_TRUE(WaitForCondition(
1397 base::Bind(&MockMediaPlayerManager::HasFirstFrame,
1398 base::Unretained(&manager_), DemuxerStream::VIDEO)));
1399
1400 EXPECT_TRUE(AlmostEqual(manager_.FirstFramePTS(DemuxerStream::AUDIO),
1401 manager_.FirstFramePTS(DemuxerStream::VIDEO), 10));
1402
1403 EXPECT_TRUE(AlmostEqual(manager_.FirstFrameTime(DemuxerStream::AUDIO),
1404 manager_.FirstFrameTime(DemuxerStream::VIDEO), 50));
1405
1406 // The playback should start at |seek_position|
1407 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
1408 }
1409
1410 TEST_F(MediaCodecPlayerTest, AVPrerollVideoEndsWhilePrerolling) {
1411 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1412
1413 // Test that when one stream ends in the preroll phase and another is not
1414 // the preroll finishes and playback continues after it.
1415
1416 base::TimeDelta audio_duration = base::TimeDelta::FromMilliseconds(1100);
1417 base::TimeDelta video_duration = base::TimeDelta::FromMilliseconds(900);
1418 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1419 base::TimeDelta video_preroll_intvl = base::TimeDelta::FromMilliseconds(200);
1420
1421 base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
1422 base::TimeDelta preroll_timeout = base::TimeDelta::FromMilliseconds(400);
1423
1424 demuxer_->SetVideoPrerollInterval(video_preroll_intvl);
1425
1426 demuxer_->SetAudioFactory(
1427 scoped_ptr<AudioFactory>(new AudioFactory(audio_duration)));
1428 demuxer_->SetVideoFactory(
1429 scoped_ptr<VideoFactory>(new VideoFactory(video_duration)));
1430
1431 CreatePlayer();
1432 SetVideoSurface();
1433
1434 // Set special testing callback to receive PTS from decoders.
1435 player_->SetDecodersTimeCallbackForTests(
1436 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate,
1437 base::Unretained(&manager_)));
1438
1439 // Wait till the player is initialized on media thread.
1440 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
1441 base::Unretained(demuxer_))));
1442
1443 // Post configuration after the player has been initialized.
1444 demuxer_->PostInternalConfigs();
1445
1446 // Issue SeekTo().
1447 player_->SeekTo(seek_position);
1448
1449 // Start the playback.
1450 player_->Start();
1451
1452 // The video decoder should start prerolling
1453 // Wait till preroll starts.
1454 EXPECT_TRUE(WaitForCondition(
1455 base::Bind(&MediaCodecPlayer::IsPrerollingForTests,
1456 base::Unretained(player_), DemuxerStream::VIDEO),
1457 start_timeout));
1458
1459 // Wait for playback to start.
1460 EXPECT_TRUE(
1461 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1462 base::Unretained(&manager_)),
1463 preroll_timeout));
1464
1465 EXPECT_TRUE(manager_.HasFirstFrame(DemuxerStream::AUDIO));
1466
1467 // Play till completion.
1468 EXPECT_TRUE(
1469 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
1470 base::Unretained(&manager_))));
1471
1472 // There should not be any video frames.
1473 EXPECT_FALSE(manager_.HasFirstFrame(DemuxerStream::VIDEO));
1474 }
1475
1061 } // namespace media 1476 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_player.cc ('k') | media/base/android/media_codec_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698