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

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

Issue 1242913004: MediaCodecPlayer implementation (stage 3 - browser seek and surface change) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-seek
Patch Set: Addressed Min comments, added unit tests. Created 5 years, 5 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override { 168 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
169 unit->is_key_frame = true; 169 unit->is_key_frame = true;
170 } 170 }
171 }; 171 };
172 172
173 // VideoFactory creates a video stream from demuxer. 173 // VideoFactory creates a video stream from demuxer.
174 174
175 class VideoFactory : public TestDataFactory { 175 class VideoFactory : public TestDataFactory {
176 public: 176 public:
177 VideoFactory(base::TimeDelta duration) 177 VideoFactory(base::TimeDelta duration)
178 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod) {} 178 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod),
179 key_frame_requested_(true) {}
179 180
180 DemuxerConfigs GetConfigs() const override { 181 DemuxerConfigs GetConfigs() const override {
181 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_, 182 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_,
182 gfx::Size(320, 180)); 183 gfx::Size(320, 180));
183 } 184 }
184 185
186 void RequestKeyFrame() { key_frame_requested_ = true; }
187
185 protected: 188 protected:
186 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override { 189 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
187 // The frames are taken from High profile and some are B-frames. 190 // The frames are taken from High profile and some are B-frames.
188 // The first 4 frames appear in the file in the following order: 191 // The first 4 frames appear in the file in the following order:
189 // 192 //
190 // Frames: I P B P 193 // Frames: I P B P
191 // Decoding order: 0 1 2 3 194 // Decoding order: 0 1 2 3
192 // Presentation order: 0 2 1 4(3) 195 // Presentation order: 0 2 1 4(3)
193 // 196 //
194 // I keep the last PTS to be 3 for simplicity. 197 // I keep the last PTS to be 3 for simplicity.
195 198
196 // Swap pts for second and third frames. Make first frame a key frame. 199 // Swap pts for second and third frames. Make first frame a key frame.
197 switch (index_in_chunk) { 200 switch (index_in_chunk) {
198 case 0: // first frame 201 case 0: // first frame
199 unit->is_key_frame = true; 202 unit->is_key_frame = key_frame_requested_;
203 key_frame_requested_ = false;
200 break; 204 break;
201 case 1: // second frame 205 case 1: // second frame
202 unit->timestamp += frame_period_; 206 unit->timestamp += frame_period_;
203 break; 207 break;
204 case 2: // third frame 208 case 2: // third frame
205 unit->timestamp -= frame_period_; 209 unit->timestamp -= frame_period_;
206 break; 210 break;
207 case 3: // fourth frame, do not modify 211 case 3: // fourth frame, do not modify
208 break; 212 break;
209 default: 213 default:
210 NOTREACHED(); 214 NOTREACHED();
211 break; 215 break;
212 } 216 }
213 } 217 }
218
219 private:
220 bool key_frame_requested_;
214 }; 221 };
215 222
216 // Mock of DemuxerAndroid for testing purpose. 223 // Mock of DemuxerAndroid for testing purpose.
217 224
218 class MockDemuxerAndroid : public DemuxerAndroid { 225 class MockDemuxerAndroid : public DemuxerAndroid {
219 public: 226 public:
220 MockDemuxerAndroid() : client_(nullptr) {} 227 MockDemuxerAndroid() : client_(nullptr), num_browser_seeks_(0) {}
221 ~MockDemuxerAndroid() override {} 228 ~MockDemuxerAndroid() override {}
222 229
223 // DemuxerAndroid implementation 230 // DemuxerAndroid implementation
224 void Initialize(DemuxerAndroidClient* client) override; 231 void Initialize(DemuxerAndroidClient* client) override;
225 void RequestDemuxerData(DemuxerStream::Type type) override; 232 void RequestDemuxerData(DemuxerStream::Type type) override;
226 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 233 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
227 bool is_browser_seek) override; 234 bool is_browser_seek) override;
228 235
229 // Sets the audio data factory. 236 // Sets the audio data factory.
230 void SetAudioFactory(scoped_ptr<TestDataFactory> factory) { 237 void SetAudioFactory(scoped_ptr<AudioFactory> factory) {
231 audio_factory_ = factory.Pass(); 238 audio_factory_ = factory.Pass();
232 } 239 }
233 240
234 // Sets the video data factory. 241 // Sets the video data factory.
235 void SetVideoFactory(scoped_ptr<TestDataFactory> factory) { 242 void SetVideoFactory(scoped_ptr<VideoFactory> factory) {
236 video_factory_ = factory.Pass(); 243 video_factory_ = factory.Pass();
237 } 244 }
238 245
239 // Post DemuxerConfigs to the client (i.e. the player) on correct thread. 246 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
240 void PostConfigs(const DemuxerConfigs& configs); 247 void PostConfigs(const DemuxerConfigs& configs);
241 248
242 // Post DemuxerConfigs derived from data factories that has been set. 249 // Post DemuxerConfigs derived from data factories that has been set.
243 void PostInternalConfigs(); 250 void PostInternalConfigs();
244 251
245 // Conditions to wait for. 252 // Conditions to wait for.
246 bool IsInitialized() const { return client_; } 253 bool IsInitialized() const { return client_; }
247 bool HasPendingConfigs() const { return pending_configs_; } 254 bool HasPendingConfigs() const { return pending_configs_; }
255 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
248 256
249 private: 257 private:
250 DemuxerAndroidClient* client_; 258 DemuxerAndroidClient* client_;
251 scoped_ptr<DemuxerConfigs> pending_configs_; 259 scoped_ptr<DemuxerConfigs> pending_configs_;
252 scoped_ptr<TestDataFactory> audio_factory_; 260 scoped_ptr<AudioFactory> audio_factory_;
253 scoped_ptr<TestDataFactory> video_factory_; 261 scoped_ptr<VideoFactory> video_factory_;
262 int num_browser_seeks_;
254 263
255 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); 264 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
256 }; 265 };
257 266
258 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) { 267 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) {
259 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__; 268 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
260 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 269 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
261 270
262 client_ = client; 271 client_ = client;
263 if (pending_configs_) 272 if (pending_configs_)
(...skipping 21 matching lines...) Expand all
285 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable, 294 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable,
286 base::Unretained(client_), chunk), 295 base::Unretained(client_), chunk),
287 delay); 296 delay);
288 } 297 }
289 298
290 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 299 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
291 bool is_browser_seek) { 300 bool is_browser_seek) {
292 // Tell data factories to start next chunk with the new timestamp. 301 // Tell data factories to start next chunk with the new timestamp.
293 if (audio_factory_) 302 if (audio_factory_)
294 audio_factory_->SeekTo(time_to_seek); 303 audio_factory_->SeekTo(time_to_seek);
295 if (video_factory_) 304 if (video_factory_) {
296 video_factory_->SeekTo(time_to_seek); 305 video_factory_->SeekTo(time_to_seek);
306 video_factory_->RequestKeyFrame();
307 }
308
309 if (is_browser_seek)
310 ++num_browser_seeks_;
297 311
298 // Post OnDemuxerSeekDone() to the player. 312 // Post OnDemuxerSeekDone() to the player.
299 DCHECK(client_); 313 DCHECK(client_);
300 base::TimeDelta reported_seek_time = 314 base::TimeDelta reported_seek_time =
301 is_browser_seek ? time_to_seek : kNoTimestamp(); 315 is_browser_seek ? time_to_seek : kNoTimestamp();
302 GetMediaTaskRunner()->PostTask( 316 GetMediaTaskRunner()->PostTask(
303 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone, 317 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
304 base::Unretained(client_), reported_seek_time)); 318 base::Unretained(client_), reported_seek_time));
305 } 319 }
306 320
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 ~MediaCodecPlayerTest() override; 354 ~MediaCodecPlayerTest() override;
341 355
342 // Conditions to wait for. 356 // Conditions to wait for.
343 bool IsPaused() const { return !(player_ && player_->IsPlaying()); } 357 bool IsPaused() const { return !(player_ && player_->IsPlaying()); }
344 358
345 protected: 359 protected:
346 typedef base::Callback<bool()> Predicate; 360 typedef base::Callback<bool()> Predicate;
347 361
348 void CreatePlayer(); 362 void CreatePlayer();
349 void SetVideoSurface(); 363 void SetVideoSurface();
364 void SetVideoSurfaceB();
365 void RemoveVideoSurface();
350 366
351 // Waits for condition to become true or for timeout to expire. 367 // Waits for condition to become true or for timeout to expire.
352 // Returns true if the condition becomes true. 368 // Returns true if the condition becomes true.
353 bool WaitForCondition(const Predicate& condition, 369 bool WaitForCondition(const Predicate& condition,
354 const base::TimeDelta& timeout = kDefaultTimeout); 370 const base::TimeDelta& timeout = kDefaultTimeout);
355 371
356 // Waits for timeout to expire. 372 // Waits for timeout to expire.
357 void WaitForDelay(const base::TimeDelta& timeout); 373 void WaitForDelay(const base::TimeDelta& timeout);
358 374
359 // Waits till playback position as determined by maximal reported pts 375 // Waits till playback position as determined by maximal reported pts
360 // reaches the given value or for timeout to expire. Returns true if the 376 // reaches the given value or for timeout to expire. Returns true if the
361 // playback passed the given position. 377 // playback passed the given position.
362 bool WaitForPlaybackPassedPosition( 378 bool WaitForPlaybackPassedPosition(
363 const base::TimeDelta& pts, 379 const base::TimeDelta& pts,
364 const base::TimeDelta& timeout = kDefaultTimeout); 380 const base::TimeDelta& timeout = kDefaultTimeout);
365 381
382 // Helper method that starts video only stream. Waits till it actually
383 // started.
384 void StartVideoPlayback(base::TimeDelta duration);
385
366 base::MessageLoop message_loop_; 386 base::MessageLoop message_loop_;
367 MockMediaPlayerManager manager_; 387 MockMediaPlayerManager manager_;
368 MockDemuxerAndroid* demuxer_; // owned by player_ 388 MockDemuxerAndroid* demuxer_; // owned by player_
369 scoped_refptr<gfx::SurfaceTexture> surface_texture_; 389 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
390 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
370 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread() 391 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread()
371 392
372 private: 393 private:
373 bool is_timeout_expired() const { return is_timeout_expired_; } 394 bool is_timeout_expired() const { return is_timeout_expired_; }
374 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; } 395 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; }
375 396
376 bool is_timeout_expired_; 397 bool is_timeout_expired_;
377 398
378 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest); 399 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest);
379 }; 400 };
(...skipping 13 matching lines...) Expand all
393 0, // player_id 414 0, // player_id
394 manager_.GetWeakPtr(), 415 manager_.GetWeakPtr(),
395 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested, 416 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested,
396 base::Unretained(&manager_)), 417 base::Unretained(&manager_)),
397 scoped_ptr<MockDemuxerAndroid>(demuxer_), GURL()); 418 scoped_ptr<MockDemuxerAndroid>(demuxer_), GURL());
398 419
399 DCHECK(player_); 420 DCHECK(player_);
400 } 421 }
401 422
402 void MediaCodecPlayerTest::SetVideoSurface() { 423 void MediaCodecPlayerTest::SetVideoSurface() {
403 surface_texture_ = gfx::SurfaceTexture::Create(0); 424 surface_texture_a_ = gfx::SurfaceTexture::Create(0);
404 gfx::ScopedJavaSurface surface(surface_texture_.get()); 425 gfx::ScopedJavaSurface surface(surface_texture_a_.get());
405 426
406 ASSERT_NE(nullptr, player_); 427 ASSERT_NE(nullptr, player_);
407 player_->SetVideoSurface(surface.Pass()); 428 player_->SetVideoSurface(surface.Pass());
408 } 429 }
409 430
431 void MediaCodecPlayerTest::SetVideoSurfaceB() {
432 surface_texture_b_ = gfx::SurfaceTexture::Create(1);
433 gfx::ScopedJavaSurface surface(surface_texture_b_.get());
434
435 ASSERT_NE(nullptr, player_);
436 player_->SetVideoSurface(surface.Pass());
437 }
438
439 void MediaCodecPlayerTest::RemoveVideoSurface() {
440 player_->SetVideoSurface(gfx::ScopedJavaSurface());
441 surface_texture_a_ = NULL;
442 }
443
410 bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition, 444 bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition,
411 const base::TimeDelta& timeout) { 445 const base::TimeDelta& timeout) {
412 // Let the message_loop_ process events. 446 // Let the message_loop_ process events.
413 // We start the timer and RunUntilIdle() until it signals. 447 // We start the timer and RunUntilIdle() until it signals.
414 448
415 SetTimeoutExpired(false); 449 SetTimeoutExpired(false);
416 450
417 base::Timer timer(false, false); 451 base::Timer timer(false, false);
418 timer.Start(FROM_HERE, timeout, 452 timer.Start(FROM_HERE, timeout,
419 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired, 453 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired,
(...skipping 17 matching lines...) Expand all
437 471
438 bool MediaCodecPlayerTest::WaitForPlaybackPassedPosition( 472 bool MediaCodecPlayerTest::WaitForPlaybackPassedPosition(
439 const base::TimeDelta& pts, 473 const base::TimeDelta& pts,
440 const base::TimeDelta& timeout) { 474 const base::TimeDelta& timeout) {
441 return WaitForCondition( 475 return WaitForCondition(
442 base::Bind(&MockMediaPlayerManager::IsPlaybackPassedPosition, 476 base::Bind(&MockMediaPlayerManager::IsPlaybackPassedPosition,
443 base::Unretained(&manager_), pts), 477 base::Unretained(&manager_), pts),
444 timeout); 478 timeout);
445 } 479 }
446 480
481 void MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration) {
482 const base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
483
484 demuxer_->SetVideoFactory(
485 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
486
487 CreatePlayer();
488 SetVideoSurface();
489
490 // Wait till the player is initialized on media thread.
491 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
492 base::Unretained(demuxer_))));
493
494 // Post configuration after the player has been initialized.
495 demuxer_->PostInternalConfigs();
496
497 // Start the player.
498 EXPECT_FALSE(manager_.IsPlaybackStarted());
499 player_->Start();
500
501 // Wait for playback to start.
502 EXPECT_TRUE(
503 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
504 base::Unretained(&manager_)),
505 start_timeout));
506 }
507
447 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) { 508 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) {
448 // Post configuration when there is no player yet. 509 // Post configuration when there is no player yet.
449 EXPECT_EQ(nullptr, player_); 510 EXPECT_EQ(nullptr, player_);
450 511
451 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); 512 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
452 513
453 demuxer_->PostConfigs( 514 demuxer_->PostConfigs(
454 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration)); 515 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration));
455 516
456 // Wait until the configuration gets to the media thread. 517 // Wait until the configuration gets to the media thread.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 base::TimeDelta audio_pts_delay = base::TimeDelta::FromMilliseconds(100); 606 base::TimeDelta audio_pts_delay = base::TimeDelta::FromMilliseconds(100);
546 EXPECT_LT(duration - audio_pts_delay, manager_.pts_stat_.max()); 607 EXPECT_LT(duration - audio_pts_delay, manager_.pts_stat_.max());
547 } 608 }
548 609
549 TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) { 610 TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) {
550 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 611 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
551 612
552 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); 613 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
553 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500); 614 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
554 615
555 demuxer_->SetVideoFactory( 616 StartVideoPlayback(duration);
556 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
557 617
558 CreatePlayer(); 618 // Wait till completion.
559 SetVideoSurface();
560
561 // Wait till the player is initialized on media thread.
562 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
563 base::Unretained(demuxer_))));
564
565 // Post configuration after the player has been initialized.
566 demuxer_->PostInternalConfigs();
567
568 EXPECT_FALSE(manager_.IsPlaybackCompleted());
569
570 player_->Start();
571
572 EXPECT_TRUE( 619 EXPECT_TRUE(
573 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted, 620 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
574 base::Unretained(&manager_)), 621 base::Unretained(&manager_)),
575 timeout)); 622 timeout));
576 623
577 EXPECT_LE(duration, manager_.pts_stat_.max()); 624 EXPECT_LE(duration, manager_.pts_stat_.max());
578 } 625 }
579 626
580 TEST_F(MediaCodecPlayerTest, AudioSeekAfterStop) { 627 TEST_F(MediaCodecPlayerTest, AudioSeekAfterStop) {
581 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 628 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 player_->SeekTo(base::TimeDelta::FromSeconds(3)); 782 player_->SeekTo(base::TimeDelta::FromSeconds(3));
736 player_->SeekTo(base::TimeDelta::FromSeconds(4)); 783 player_->SeekTo(base::TimeDelta::FromSeconds(4));
737 player_->SeekTo(base::TimeDelta::FromSeconds(5)); 784 player_->SeekTo(base::TimeDelta::FromSeconds(5));
738 785
739 // Make sure that we reached the last timestamp within default timeout, 786 // Make sure that we reached the last timestamp within default timeout,
740 // i.e. 200 ms. 787 // i.e. 200 ms.
741 EXPECT_TRUE(WaitForPlaybackPassedPosition(base::TimeDelta::FromSeconds(5))); 788 EXPECT_TRUE(WaitForPlaybackPassedPosition(base::TimeDelta::FromSeconds(5)));
742 EXPECT_TRUE(player_->IsPlaying()); 789 EXPECT_TRUE(player_->IsPlaying());
743 } 790 }
744 791
792 TEST_F(MediaCodecPlayerTest, VideoReplaceSurface) {
793 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
794
795 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
796 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
797
798 StartVideoPlayback(duration);
799
800 // Wait for some time and check statistics.
801 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
802
803 // Make sure we played at least 100 ms.
804 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
805
806 // Set new video surface without removing the old one.
807 SetVideoSurfaceB();
808
809 // We should receive a browser seek request.
810 EXPECT_TRUE(WaitForCondition(
811 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
812 base::Unretained(demuxer_))));
813
814 // Playback should continue with a new surface. Wait till completion.
815 EXPECT_TRUE(
816 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
817 base::Unretained(&manager_)),
818 timeout));
819 EXPECT_LE(duration, manager_.pts_stat_.max());
820 }
821
822 TEST_F(MediaCodecPlayerTest, VideoRemoveAndSetSurface) {
823 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
824
825 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
826
827 StartVideoPlayback(duration);
828
829 // Wait for some time and check statistics.
830 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
831
832 // Make sure we played at least 100 ms.
833 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
834
835 // Remove video surface.
836 RemoveVideoSurface();
837
838 // We should be stuck waiting for the new surface.
839 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
840 EXPECT_FALSE(player_->IsPlaying());
841
842 // Save last PTS and clear statistics.
843 base::TimeDelta max_pts_before_removal = manager_.pts_stat_.max();
844 manager_.pts_stat_.Clear();
845
846 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
847 EXPECT_FALSE(manager_.IsPlaybackStarted());
848
849 // Extra RemoveVideoSurface() should not change anything.
850 RemoveVideoSurface();
851
852 // Set another video surface.
853 SetVideoSurfaceB();
854
855 // We should receive a browser seek request.
856 EXPECT_TRUE(WaitForCondition(
857 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
858 base::Unretained(demuxer_))));
859
860 // Playback should continue with a new surface. Wait till it starts again.
861 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
862 EXPECT_TRUE(
863 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
864 base::Unretained(&manager_)),
865 reconfigure_timeout));
866
867 // Timestamps should not go back.
868 EXPECT_LE(max_pts_before_removal, manager_.pts_stat_.max());
869 }
870
871 TEST_F(MediaCodecPlayerTest, VideoBackgroundForeground) {
872 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
873
874 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
875
876 StartVideoPlayback(duration);
877
878 // Wait for some time and check statistics.
879 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
880
881 // Make sure we played at least 100 ms.
882 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
883
884 // When the user presses Tasks button Chrome calls Pause() and Release().
885 player_->Pause(true);
886 player_->Release();
887
888 // Make sure we are not playing any more.
889 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
890 EXPECT_FALSE(player_->IsPlaying());
891
892 // Save last PTS and clear statistics.
893 base::TimeDelta max_pts_before_backgrounding = manager_.pts_stat_.max();
894 manager_.pts_stat_.Clear();
895
896 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
897 EXPECT_FALSE(manager_.IsPlaybackStarted());
898
899 // Emulate that we returned to the foreground: set video surface and start
900 // the player.
901 SetVideoSurface();
902 player_->Start();
903
904 // We should receive a browser seek request.
905 EXPECT_TRUE(WaitForCondition(
906 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
907 base::Unretained(demuxer_))));
908
909 // Wait for playback to start again.
910 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
911 EXPECT_TRUE(
912 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
913 base::Unretained(&manager_)),
914 reconfigure_timeout));
915
916 // Timestamps should not go back.
917 EXPECT_LE(max_pts_before_backgrounding, manager_.pts_stat_.max());
918 }
919
745 } // namespace media 920 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698