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

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: Rebased, changed DCHECKs. 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // The method used to compare two TimeDelta values in expectations. 51 // The method used to compare two TimeDelta values in expectations.
52 bool AlmostEqual(base::TimeDelta a, base::TimeDelta b, double tolerance_ms) { 52 bool AlmostEqual(base::TimeDelta a, base::TimeDelta b, double tolerance_ms) {
53 return (a - b).magnitude().InMilliseconds() <= tolerance_ms; 53 return (a - b).magnitude().InMilliseconds() <= tolerance_ms;
54 } 54 }
55 55
56 // Mock of MediaPlayerManager for testing purpose. 56 // Mock of MediaPlayerManager for testing purpose.
57 57
58 class MockMediaPlayerManager : public MediaPlayerManager { 58 class MockMediaPlayerManager : public MediaPlayerManager {
59 public: 59 public:
60 MockMediaPlayerManager() 60 MockMediaPlayerManager()
61 : playback_completed_(false), weak_ptr_factory_(this) {} 61 : playback_completed_(false),
62 num_seeks_completed_(0),
63 weak_ptr_factory_(this) {}
62 ~MockMediaPlayerManager() override {} 64 ~MockMediaPlayerManager() override {}
63 65
64 MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; } 66 MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; }
65 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return nullptr; } 67 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return nullptr; }
66 68
67 void OnTimeUpdate(int player_id, 69 void OnTimeUpdate(int player_id,
68 base::TimeDelta current_timestamp, 70 base::TimeDelta current_timestamp,
69 base::TimeTicks current_time_ticks) override { 71 base::TimeTicks current_time_ticks) override {
70 pts_stat_.AddValue(current_timestamp); 72 pts_stat_.AddValue(current_timestamp);
71 } 73 }
72 74
73 void OnMediaMetadataChanged(int player_id, 75 void OnMediaMetadataChanged(int player_id,
74 base::TimeDelta duration, 76 base::TimeDelta duration,
75 int width, 77 int width,
76 int height, 78 int height,
77 bool success) override { 79 bool success) override {
78 media_metadata_.duration = duration; 80 media_metadata_.duration = duration;
79 media_metadata_.width = width; 81 media_metadata_.width = width;
80 media_metadata_.height = height; 82 media_metadata_.height = height;
81 media_metadata_.modified = true; 83 media_metadata_.modified = true;
82 } 84 }
83 85
84 void OnPlaybackComplete(int player_id) override { 86 void OnPlaybackComplete(int player_id) override {
85 playback_completed_ = true; 87 playback_completed_ = true;
86 } 88 }
87 89
88 void OnMediaInterrupted(int player_id) override {} 90 void OnMediaInterrupted(int player_id) override {}
89 void OnBufferingUpdate(int player_id, int percentage) override {} 91 void OnBufferingUpdate(int player_id, int percentage) override {}
90 void OnSeekComplete(int player_id, 92 void OnSeekComplete(int player_id,
91 const base::TimeDelta& current_time) override {} 93 const base::TimeDelta& current_time) override {
94 ++num_seeks_completed_;
95 }
92 void OnError(int player_id, int error) override {} 96 void OnError(int player_id, int error) override {}
93 void OnVideoSizeChanged(int player_id, int width, int height) override {} 97 void OnVideoSizeChanged(int player_id, int width, int height) override {}
94 void OnAudibleStateChanged(int player_id, bool is_audible_now) override {} 98 void OnAudibleStateChanged(int player_id, bool is_audible_now) override {}
95 void OnWaitingForDecryptionKey(int player_id) override {} 99 void OnWaitingForDecryptionKey(int player_id) override {}
96 MediaPlayerAndroid* GetFullscreenPlayer() override { return nullptr; } 100 MediaPlayerAndroid* GetFullscreenPlayer() override { return nullptr; }
97 MediaPlayerAndroid* GetPlayer(int player_id) override { return nullptr; } 101 MediaPlayerAndroid* GetPlayer(int player_id) override { return nullptr; }
98 bool RequestPlay(int player_id) override { return true; } 102 bool RequestPlay(int player_id) override { return true; }
99 103
100 void OnMediaResourcesRequested(int player_id) {} 104 void OnMediaResourcesRequested(int player_id) {}
101 105
102 base::WeakPtr<MockMediaPlayerManager> GetWeakPtr() { 106 base::WeakPtr<MockMediaPlayerManager> GetWeakPtr() {
103 return weak_ptr_factory_.GetWeakPtr(); 107 return weak_ptr_factory_.GetWeakPtr();
104 } 108 }
105 109
106 // Conditions to wait for. 110 // Conditions to wait for.
107 bool IsMetadataChanged() const { return media_metadata_.modified; } 111 bool IsMetadataChanged() const { return media_metadata_.modified; }
108 bool IsPlaybackCompleted() const { return playback_completed_; } 112 bool IsPlaybackCompleted() const { return playback_completed_; }
109 bool IsPlaybackStarted() const { return pts_stat_.num_values() > 0; } 113 bool IsPlaybackStarted() const { return pts_stat_.num_values() > 0; }
110 bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const { 114 bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const {
111 return pts_stat_.max() > pts; 115 return pts_stat_.max() > pts;
112 } 116 }
117 bool IsSeekCompleted() const { return num_seeks_completed_ > 0; }
113 118
114 struct MediaMetadata { 119 struct MediaMetadata {
115 base::TimeDelta duration; 120 base::TimeDelta duration;
116 int width; 121 int width;
117 int height; 122 int height;
118 bool modified; 123 bool modified;
119 MediaMetadata() : width(0), height(0), modified(false) {} 124 MediaMetadata() : width(0), height(0), modified(false) {}
120 }; 125 };
121 MediaMetadata media_metadata_; 126 MediaMetadata media_metadata_;
122 127
123 Minimax<base::TimeDelta> pts_stat_; 128 Minimax<base::TimeDelta> pts_stat_;
124 129
125 private: 130 private:
126 bool playback_completed_; 131 bool playback_completed_;
132 int num_seeks_completed_;
127 133
128 base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_; 134 base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_;
129 135
130 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager); 136 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
131 }; 137 };
132 138
133 // Helper method that creates demuxer configuration. 139 // Helper method that creates demuxer configuration.
134 140
135 DemuxerConfigs CreateAudioVideoConfigs(const base::TimeDelta& duration, 141 DemuxerConfigs CreateAudioVideoConfigs(const base::TimeDelta& duration,
136 const gfx::Size& video_size) { 142 const gfx::Size& video_size) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override { 174 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
169 unit->is_key_frame = true; 175 unit->is_key_frame = true;
170 } 176 }
171 }; 177 };
172 178
173 // VideoFactory creates a video stream from demuxer. 179 // VideoFactory creates a video stream from demuxer.
174 180
175 class VideoFactory : public TestDataFactory { 181 class VideoFactory : public TestDataFactory {
176 public: 182 public:
177 VideoFactory(base::TimeDelta duration) 183 VideoFactory(base::TimeDelta duration)
178 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod) {} 184 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod),
185 key_frame_requested_(true) {}
179 186
180 DemuxerConfigs GetConfigs() const override { 187 DemuxerConfigs GetConfigs() const override {
181 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_, 188 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_,
182 gfx::Size(320, 180)); 189 gfx::Size(320, 180));
183 } 190 }
184 191
192 void RequestKeyFrame() { key_frame_requested_ = true; }
193
185 protected: 194 protected:
186 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override { 195 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
187 // The frames are taken from High profile and some are B-frames. 196 // 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: 197 // The first 4 frames appear in the file in the following order:
189 // 198 //
190 // Frames: I P B P 199 // Frames: I P B P
191 // Decoding order: 0 1 2 3 200 // Decoding order: 0 1 2 3
192 // Presentation order: 0 2 1 4(3) 201 // Presentation order: 0 2 1 4(3)
193 // 202 //
194 // I keep the last PTS to be 3 for simplicity. 203 // I keep the last PTS to be 3 for simplicity.
195 204
196 // Swap pts for second and third frames. Make first frame a key frame. 205 // Swap pts for second and third frames. Make first frame a key frame.
197 switch (index_in_chunk) { 206 switch (index_in_chunk) {
198 case 0: // first frame 207 case 0: // first frame
199 unit->is_key_frame = true; 208 unit->is_key_frame = key_frame_requested_;
209 key_frame_requested_ = false;
200 break; 210 break;
201 case 1: // second frame 211 case 1: // second frame
202 unit->timestamp += frame_period_; 212 unit->timestamp += frame_period_;
203 break; 213 break;
204 case 2: // third frame 214 case 2: // third frame
205 unit->timestamp -= frame_period_; 215 unit->timestamp -= frame_period_;
206 break; 216 break;
207 case 3: // fourth frame, do not modify 217 case 3: // fourth frame, do not modify
208 break; 218 break;
209 default: 219 default:
210 NOTREACHED(); 220 NOTREACHED();
211 break; 221 break;
212 } 222 }
213 } 223 }
224
225 private:
226 bool key_frame_requested_;
214 }; 227 };
215 228
216 // Mock of DemuxerAndroid for testing purpose. 229 // Mock of DemuxerAndroid for testing purpose.
217 230
218 class MockDemuxerAndroid : public DemuxerAndroid { 231 class MockDemuxerAndroid : public DemuxerAndroid {
219 public: 232 public:
220 MockDemuxerAndroid() : client_(nullptr) {} 233 MockDemuxerAndroid()
234 : client_(nullptr), num_seeks_(0), num_browser_seeks_(0) {}
221 ~MockDemuxerAndroid() override {} 235 ~MockDemuxerAndroid() override {}
222 236
223 // DemuxerAndroid implementation 237 // DemuxerAndroid implementation
224 void Initialize(DemuxerAndroidClient* client) override; 238 void Initialize(DemuxerAndroidClient* client) override;
225 void RequestDemuxerData(DemuxerStream::Type type) override; 239 void RequestDemuxerData(DemuxerStream::Type type) override;
226 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 240 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
227 bool is_browser_seek) override; 241 bool is_browser_seek) override;
228 242
229 // Sets the audio data factory. 243 // Sets the audio data factory.
230 void SetAudioFactory(scoped_ptr<TestDataFactory> factory) { 244 void SetAudioFactory(scoped_ptr<AudioFactory> factory) {
231 audio_factory_ = factory.Pass(); 245 audio_factory_ = factory.Pass();
232 } 246 }
233 247
234 // Sets the video data factory. 248 // Sets the video data factory.
235 void SetVideoFactory(scoped_ptr<TestDataFactory> factory) { 249 void SetVideoFactory(scoped_ptr<VideoFactory> factory) {
236 video_factory_ = factory.Pass(); 250 video_factory_ = factory.Pass();
237 } 251 }
238 252
253 // Sets the delay in OnDemuxerSeekDone response.
254 void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; }
255
239 // Post DemuxerConfigs to the client (i.e. the player) on correct thread. 256 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
240 void PostConfigs(const DemuxerConfigs& configs); 257 void PostConfigs(const DemuxerConfigs& configs);
241 258
242 // Post DemuxerConfigs derived from data factories that has been set. 259 // Post DemuxerConfigs derived from data factories that has been set.
243 void PostInternalConfigs(); 260 void PostInternalConfigs();
244 261
245 // Conditions to wait for. 262 // Conditions to wait for.
246 bool IsInitialized() const { return client_; } 263 bool IsInitialized() const { return client_; }
247 bool HasPendingConfigs() const { return pending_configs_; } 264 bool HasPendingConfigs() const { return pending_configs_; }
265 bool ReceivedSeekRequest() const { return num_seeks_ > 0; }
266 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
248 267
249 private: 268 private:
250 DemuxerAndroidClient* client_; 269 DemuxerAndroidClient* client_;
251 scoped_ptr<DemuxerConfigs> pending_configs_; 270 scoped_ptr<DemuxerConfigs> pending_configs_;
252 scoped_ptr<TestDataFactory> audio_factory_; 271 scoped_ptr<AudioFactory> audio_factory_;
253 scoped_ptr<TestDataFactory> video_factory_; 272 scoped_ptr<VideoFactory> video_factory_;
273 base::TimeDelta seek_done_delay_;
274 int num_seeks_;
275 int num_browser_seeks_;
254 276
255 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid); 277 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
256 }; 278 };
257 279
258 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) { 280 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) {
259 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__; 281 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
260 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 282 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
261 283
262 client_ = client; 284 client_ = client;
263 if (pending_configs_) 285 if (pending_configs_)
(...skipping 21 matching lines...) Expand all
285 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable, 307 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable,
286 base::Unretained(client_), chunk), 308 base::Unretained(client_), chunk),
287 delay); 309 delay);
288 } 310 }
289 311
290 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek, 312 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
291 bool is_browser_seek) { 313 bool is_browser_seek) {
292 // Tell data factories to start next chunk with the new timestamp. 314 // Tell data factories to start next chunk with the new timestamp.
293 if (audio_factory_) 315 if (audio_factory_)
294 audio_factory_->SeekTo(time_to_seek); 316 audio_factory_->SeekTo(time_to_seek);
295 if (video_factory_) 317 if (video_factory_) {
296 video_factory_->SeekTo(time_to_seek); 318 video_factory_->SeekTo(time_to_seek);
319 video_factory_->RequestKeyFrame();
320 }
321
322 ++num_seeks_;
323 if (is_browser_seek)
324 ++num_browser_seeks_;
297 325
298 // Post OnDemuxerSeekDone() to the player. 326 // Post OnDemuxerSeekDone() to the player.
299 DCHECK(client_); 327 DCHECK(client_);
300 base::TimeDelta reported_seek_time = 328 base::TimeDelta reported_seek_time =
301 is_browser_seek ? time_to_seek : kNoTimestamp(); 329 is_browser_seek ? time_to_seek : kNoTimestamp();
302 GetMediaTaskRunner()->PostTask( 330 GetMediaTaskRunner()->PostDelayedTask(
303 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone, 331 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
304 base::Unretained(client_), reported_seek_time)); 332 base::Unretained(client_), reported_seek_time),
333 seek_done_delay_);
305 } 334 }
306 335
307 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) { 336 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) {
308 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid, PostConfigs, configs); 337 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid, PostConfigs, configs);
309 338
310 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__; 339 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
311 340
312 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 341 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
313 342
314 if (client_) 343 if (client_)
(...skipping 25 matching lines...) Expand all
340 ~MediaCodecPlayerTest() override; 369 ~MediaCodecPlayerTest() override;
341 370
342 // Conditions to wait for. 371 // Conditions to wait for.
343 bool IsPaused() const { return !(player_ && player_->IsPlaying()); } 372 bool IsPaused() const { return !(player_ && player_->IsPlaying()); }
344 373
345 protected: 374 protected:
346 typedef base::Callback<bool()> Predicate; 375 typedef base::Callback<bool()> Predicate;
347 376
348 void CreatePlayer(); 377 void CreatePlayer();
349 void SetVideoSurface(); 378 void SetVideoSurface();
379 void SetVideoSurfaceB();
380 void RemoveVideoSurface();
350 381
351 // Waits for condition to become true or for timeout to expire. 382 // Waits for condition to become true or for timeout to expire.
352 // Returns true if the condition becomes true. 383 // Returns true if the condition becomes true.
353 bool WaitForCondition(const Predicate& condition, 384 bool WaitForCondition(const Predicate& condition,
354 const base::TimeDelta& timeout = kDefaultTimeout); 385 const base::TimeDelta& timeout = kDefaultTimeout);
355 386
356 // Waits for timeout to expire. 387 // Waits for timeout to expire.
357 void WaitForDelay(const base::TimeDelta& timeout); 388 void WaitForDelay(const base::TimeDelta& timeout);
358 389
359 // Waits till playback position as determined by maximal reported pts 390 // Waits till playback position as determined by maximal reported pts
360 // reaches the given value or for timeout to expire. Returns true if the 391 // reaches the given value or for timeout to expire. Returns true if the
361 // playback has passed the given position. 392 // playback has passed the given position.
362 bool WaitForPlaybackBeyondPosition( 393 bool WaitForPlaybackBeyondPosition(
363 const base::TimeDelta& pts, 394 const base::TimeDelta& pts,
364 const base::TimeDelta& timeout = kDefaultTimeout); 395 const base::TimeDelta& timeout = kDefaultTimeout);
365 396
397 // Helper method that starts video only stream. Waits till it actually
398 // started.
399 void StartVideoPlayback(base::TimeDelta duration);
400
366 base::MessageLoop message_loop_; 401 base::MessageLoop message_loop_;
367 MockMediaPlayerManager manager_; 402 MockMediaPlayerManager manager_;
368 MockDemuxerAndroid* demuxer_; // owned by player_ 403 MockDemuxerAndroid* demuxer_; // owned by player_
369 scoped_refptr<gfx::SurfaceTexture> surface_texture_; 404 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
405 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
370 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread() 406 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread()
371 407
372 private: 408 private:
373 bool is_timeout_expired() const { return is_timeout_expired_; } 409 bool is_timeout_expired() const { return is_timeout_expired_; }
374 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; } 410 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; }
375 411
376 bool is_timeout_expired_; 412 bool is_timeout_expired_;
377 413
378 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest); 414 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest);
379 }; 415 };
(...skipping 13 matching lines...) Expand all
393 0, // player_id 429 0, // player_id
394 manager_.GetWeakPtr(), 430 manager_.GetWeakPtr(),
395 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested, 431 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested,
396 base::Unretained(&manager_)), 432 base::Unretained(&manager_)),
397 scoped_ptr<MockDemuxerAndroid>(demuxer_), GURL()); 433 scoped_ptr<MockDemuxerAndroid>(demuxer_), GURL());
398 434
399 DCHECK(player_); 435 DCHECK(player_);
400 } 436 }
401 437
402 void MediaCodecPlayerTest::SetVideoSurface() { 438 void MediaCodecPlayerTest::SetVideoSurface() {
403 surface_texture_ = gfx::SurfaceTexture::Create(0); 439 surface_texture_a_ = gfx::SurfaceTexture::Create(0);
404 gfx::ScopedJavaSurface surface(surface_texture_.get()); 440 gfx::ScopedJavaSurface surface(surface_texture_a_.get());
405 441
406 ASSERT_NE(nullptr, player_); 442 ASSERT_NE(nullptr, player_);
407 player_->SetVideoSurface(surface.Pass()); 443 player_->SetVideoSurface(surface.Pass());
408 } 444 }
409 445
446 void MediaCodecPlayerTest::SetVideoSurfaceB() {
447 surface_texture_b_ = gfx::SurfaceTexture::Create(1);
448 gfx::ScopedJavaSurface surface(surface_texture_b_.get());
449
450 ASSERT_NE(nullptr, player_);
451 player_->SetVideoSurface(surface.Pass());
452 }
453
454 void MediaCodecPlayerTest::RemoveVideoSurface() {
455 player_->SetVideoSurface(gfx::ScopedJavaSurface());
456 surface_texture_a_ = NULL;
457 }
458
410 bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition, 459 bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition,
411 const base::TimeDelta& timeout) { 460 const base::TimeDelta& timeout) {
412 // Let the message_loop_ process events. 461 // Let the message_loop_ process events.
413 // We start the timer and RunUntilIdle() until it signals. 462 // We start the timer and RunUntilIdle() until it signals.
414 463
415 SetTimeoutExpired(false); 464 SetTimeoutExpired(false);
416 465
417 base::Timer timer(false, false); 466 base::Timer timer(false, false);
418 timer.Start(FROM_HERE, timeout, 467 timer.Start(FROM_HERE, timeout,
419 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired, 468 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired,
(...skipping 17 matching lines...) Expand all
437 486
438 bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition( 487 bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition(
439 const base::TimeDelta& pts, 488 const base::TimeDelta& pts,
440 const base::TimeDelta& timeout) { 489 const base::TimeDelta& timeout) {
441 return WaitForCondition( 490 return WaitForCondition(
442 base::Bind(&MockMediaPlayerManager::IsPlaybackBeyondPosition, 491 base::Bind(&MockMediaPlayerManager::IsPlaybackBeyondPosition,
443 base::Unretained(&manager_), pts), 492 base::Unretained(&manager_), pts),
444 timeout); 493 timeout);
445 } 494 }
446 495
496 void MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration) {
497 const base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
498
499 demuxer_->SetVideoFactory(
500 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
501
502 CreatePlayer();
503 SetVideoSurface();
504
505 // Wait till the player is initialized on media thread.
506 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
507 base::Unretained(demuxer_))));
508
509 // Post configuration after the player has been initialized.
510 demuxer_->PostInternalConfigs();
511
512 // Start the player.
513 EXPECT_FALSE(manager_.IsPlaybackStarted());
514 player_->Start();
515
516 // Wait for playback to start.
517 EXPECT_TRUE(
518 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
519 base::Unretained(&manager_)),
520 start_timeout));
521 }
522
447 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) { 523 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) {
448 // Post configuration when there is no player yet. 524 // Post configuration when there is no player yet.
449 EXPECT_EQ(nullptr, player_); 525 EXPECT_EQ(nullptr, player_);
450 526
451 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); 527 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
452 528
453 demuxer_->PostConfigs( 529 demuxer_->PostConfigs(
454 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration)); 530 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration));
455 531
456 // Wait until the configuration gets to the media thread. 532 // 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); 621 base::TimeDelta audio_pts_delay = base::TimeDelta::FromMilliseconds(100);
546 EXPECT_LT(duration - audio_pts_delay, manager_.pts_stat_.max()); 622 EXPECT_LT(duration - audio_pts_delay, manager_.pts_stat_.max());
547 } 623 }
548 624
549 TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) { 625 TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) {
550 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 626 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
551 627
552 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); 628 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
553 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500); 629 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
554 630
555 demuxer_->SetVideoFactory( 631 StartVideoPlayback(duration);
556 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
557 632
558 CreatePlayer(); 633 // 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( 634 EXPECT_TRUE(
573 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted, 635 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
574 base::Unretained(&manager_)), 636 base::Unretained(&manager_)),
575 timeout)); 637 timeout));
576 638
577 EXPECT_LE(duration, manager_.pts_stat_.max()); 639 EXPECT_LE(duration, manager_.pts_stat_.max());
578 } 640 }
579 641
580 TEST_F(MediaCodecPlayerTest, AudioSeekAfterStop) { 642 TEST_F(MediaCodecPlayerTest, AudioSeekAfterStop) {
581 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 643 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 685
624 player_->Start(); 686 player_->Start();
625 687
626 // Wait for playback to start. 688 // Wait for playback to start.
627 EXPECT_TRUE( 689 EXPECT_TRUE(
628 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted, 690 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
629 base::Unretained(&manager_)))); 691 base::Unretained(&manager_))));
630 692
631 // Make sure we started from the beginninig 693 // Make sure we started from the beginninig
632 EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_.pts_stat_.min()); 694 EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_.pts_stat_.min());
695
696 // The player should have reported the seek completion to the manager.
697 EXPECT_TRUE(WaitForCondition(base::Bind(
698 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
633 } 699 }
634 700
635 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlay) { 701 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlay) {
636 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 702 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
637 703
638 // Issue Seek command immediately followed by Start. The playback should 704 // Issue Seek command immediately followed by Start. The playback should
639 // start at the seek position. 705 // start at the seek position.
640 706
641 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000); 707 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
642 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500); 708 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500);
(...skipping 10 matching lines...) Expand all
653 player_->SeekTo(seek_position); 719 player_->SeekTo(seek_position);
654 player_->Start(); 720 player_->Start();
655 721
656 // Wait for playback to start. 722 // Wait for playback to start.
657 EXPECT_TRUE( 723 EXPECT_TRUE(
658 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted, 724 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
659 base::Unretained(&manager_)))); 725 base::Unretained(&manager_))));
660 726
661 // The playback should start at |seek_position| 727 // The playback should start at |seek_position|
662 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1)); 728 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
729
730 // The player should have reported the seek completion to the manager.
731 EXPECT_TRUE(WaitForCondition(base::Bind(
732 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
663 } 733 }
664 734
665 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlayThenConfig) { 735 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlayThenConfig) {
666 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 736 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
667 737
668 // Issue Seek command immediately followed by Start but without prior demuxer 738 // Issue Seek command immediately followed by Start but without prior demuxer
669 // configuration. Start should wait for configuration. After it has been 739 // configuration. Start should wait for configuration. After it has been
670 // posted the playback should start at the seek position. 740 // posted the playback should start at the seek position.
671 741
672 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000); 742 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
(...skipping 15 matching lines...) Expand all
688 // Post configuration. 758 // Post configuration.
689 demuxer_->PostInternalConfigs(); 759 demuxer_->PostInternalConfigs();
690 760
691 // Wait for playback to start. 761 // Wait for playback to start.
692 EXPECT_TRUE( 762 EXPECT_TRUE(
693 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted, 763 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
694 base::Unretained(&manager_)))); 764 base::Unretained(&manager_))));
695 765
696 // The playback should start at |seek_position| 766 // The playback should start at |seek_position|
697 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1)); 767 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
768
769 // The player should have reported the seek completion to the manager.
770 EXPECT_TRUE(WaitForCondition(base::Bind(
771 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
698 } 772 }
699 773
700 TEST_F(MediaCodecPlayerTest, AudioSeekWhilePlaying) { 774 TEST_F(MediaCodecPlayerTest, AudioSeekWhilePlaying) {
701 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); 775 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
702 776
703 // Play for 300 ms, then issue several Seek commands in the row. 777 // Play for 300 ms, then issue several Seek commands in the row.
704 // The playback should continue at the last seek position. 778 // The playback should continue at the last seek position.
705 779
706 // To test this condition without analyzing the reported time details 780 // To test this condition without analyzing the reported time details
707 // and without introducing dependency on implementation I make a long (10s) 781 // and without introducing dependency on implementation I make a long (10s)
(...skipping 25 matching lines...) Expand all
733 807
734 // Seek forward several times. 808 // Seek forward several times.
735 player_->SeekTo(base::TimeDelta::FromSeconds(3)); 809 player_->SeekTo(base::TimeDelta::FromSeconds(3));
736 player_->SeekTo(base::TimeDelta::FromSeconds(4)); 810 player_->SeekTo(base::TimeDelta::FromSeconds(4));
737 player_->SeekTo(base::TimeDelta::FromSeconds(5)); 811 player_->SeekTo(base::TimeDelta::FromSeconds(5));
738 812
739 // Make sure that we reached the last timestamp within default timeout, 813 // Make sure that we reached the last timestamp within default timeout,
740 // i.e. 200 ms. 814 // i.e. 200 ms.
741 EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5))); 815 EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5)));
742 EXPECT_TRUE(player_->IsPlaying()); 816 EXPECT_TRUE(player_->IsPlaying());
817
818 // The player should have reported the seek completion to the manager.
819 EXPECT_TRUE(WaitForCondition(base::Bind(
820 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
821 }
822
823 TEST_F(MediaCodecPlayerTest, VideoReplaceSurface) {
824 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
825
826 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
827 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
828
829 StartVideoPlayback(duration);
830
831 // Wait for some time and check statistics.
832 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
833
834 // Make sure we played at least 100 ms.
835 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
836
837 // Set new video surface without removing the old one.
838 SetVideoSurfaceB();
839
840 // We should receive a browser seek request.
841 EXPECT_TRUE(WaitForCondition(
842 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
843 base::Unretained(demuxer_))));
844
845 // Playback should continue with a new surface. Wait till completion.
846 EXPECT_TRUE(
847 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
848 base::Unretained(&manager_)),
849 timeout));
850 EXPECT_LE(duration, manager_.pts_stat_.max());
851 }
852
853 TEST_F(MediaCodecPlayerTest, VideoRemoveAndSetSurface) {
854 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
855
856 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
857
858 StartVideoPlayback(duration);
859
860 // Wait for some time and check statistics.
861 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
862
863 // Make sure we played at least 100 ms.
864 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
865
866 // Remove video surface.
867 RemoveVideoSurface();
868
869 // We should be stuck waiting for the new surface.
870 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
871 EXPECT_FALSE(player_->IsPlaying());
872
873 // Save last PTS and clear statistics.
874 base::TimeDelta max_pts_before_removal = manager_.pts_stat_.max();
875 manager_.pts_stat_.Clear();
876
877 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
878 EXPECT_FALSE(manager_.IsPlaybackStarted());
879
880 // Extra RemoveVideoSurface() should not change anything.
881 RemoveVideoSurface();
882
883 // Set another video surface.
884 SetVideoSurfaceB();
885
886 // We should receive a browser seek request.
887 EXPECT_TRUE(WaitForCondition(
888 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
889 base::Unretained(demuxer_))));
890
891 // Playback should continue with a new surface. Wait till it starts again.
892 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
893 EXPECT_TRUE(
894 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
895 base::Unretained(&manager_)),
896 reconfigure_timeout));
897
898 // Timestamps should not go back.
899 EXPECT_LE(max_pts_before_removal, manager_.pts_stat_.max());
900 }
901
902 TEST_F(MediaCodecPlayerTest, VideoReleaseAndStart) {
903 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
904
905 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
906
907 StartVideoPlayback(duration);
908
909 // Wait for some time and check statistics.
910 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
911
912 // Make sure we played at least 100 ms.
913 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
914
915 // When the user presses Tasks button Chrome calls Pause() and Release().
916 player_->Pause(true);
917 player_->Release();
918
919 // Make sure we are not playing any more.
920 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
921 EXPECT_FALSE(player_->IsPlaying());
922
923 // Save last PTS and clear statistics.
924 base::TimeDelta max_pts_before_backgrounding = manager_.pts_stat_.max();
925 manager_.pts_stat_.Clear();
926
927 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
928 EXPECT_FALSE(manager_.IsPlaybackStarted());
929
930 // Restart.
931 SetVideoSurface();
932 player_->Start();
933
934 // We should receive a browser seek request.
935 EXPECT_TRUE(WaitForCondition(
936 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
937 base::Unretained(demuxer_))));
938
939 // Wait for playback to start again.
940 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
941 EXPECT_TRUE(
942 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
943 base::Unretained(&manager_)),
944 reconfigure_timeout));
945
946 // Timestamps should not go back.
947 EXPECT_LE(max_pts_before_backgrounding, manager_.pts_stat_.max());
948 }
949
950 TEST_F(MediaCodecPlayerTest, VideoSeekAndRelease) {
951 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
952
953 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
954 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
955
956 StartVideoPlayback(duration);
957
958 // Wait for some time and check statistics.
959 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
960
961 // Make sure we played at least 100 ms.
962 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
963
964 // Issue SeekTo() immediately followed by Release().
965 player_->SeekTo(seek_position);
966 player_->Release();
967
968 // Make sure we are not playing any more.
969 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
970 EXPECT_FALSE(player_->IsPlaying());
971
972 // The Release() should not cancel the SeekTo() and we should have received
973 // the seek request by this time.
974 EXPECT_TRUE(demuxer_->ReceivedSeekRequest());
975
976 // The player should have reported the seek completion to the manager.
977 EXPECT_TRUE(WaitForCondition(base::Bind(
978 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
979
980 // Clear statistics.
981 manager_.pts_stat_.Clear();
982
983 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
984 EXPECT_FALSE(manager_.IsPlaybackStarted());
985
986 // Restart.
987 SetVideoSurface();
988 player_->Start();
989
990 // Wait for playback to start again.
991 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
992 EXPECT_TRUE(
993 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
994 base::Unretained(&manager_)),
995 reconfigure_timeout));
996
997 // Timestamps should start at the new seek position
998 EXPECT_LE(seek_position, manager_.pts_stat_.min());
999 }
1000
1001 TEST_F(MediaCodecPlayerTest, VideoReleaseWhileWaitingForSeek) {
1002 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1003
1004 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
1005 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1006
1007 StartVideoPlayback(duration);
1008
1009 // Wait for some time and check statistics.
1010 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1011
1012 // Make sure we played at least 100 ms.
1013 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
1014
1015 // Set artificial delay in the OnDemuxerSeekDone response so we can
1016 // issue commands while the player is in the STATE_WAITING_FOR_SEEK.
1017 demuxer_->SetSeekDoneDelay(base::TimeDelta::FromMilliseconds(100));
1018
1019 // Issue SeekTo().
1020 player_->SeekTo(seek_position);
1021
1022 // Wait for the seek request to demuxer.
1023 EXPECT_TRUE(WaitForCondition(base::Bind(
1024 &MockDemuxerAndroid::ReceivedSeekRequest, base::Unretained(demuxer_))));
1025
1026 // The player is supposed to be in STATE_WAITING_FOR_SEEK. Issue Release().
1027 player_->Release();
1028
1029 // Make sure we are not playing any more.
1030 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1031 EXPECT_FALSE(player_->IsPlaying());
1032
1033 // Clear statistics.
1034 manager_.pts_stat_.Clear();
1035
1036 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1037 EXPECT_FALSE(manager_.IsPlaybackStarted());
1038
1039 // Restart.
1040 SetVideoSurface();
1041 player_->Start();
1042
1043 // Wait for playback to start again.
1044 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(1000);
1045 EXPECT_TRUE(
1046 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1047 base::Unretained(&manager_)),
1048 reconfigure_timeout));
1049
1050 // Timestamps should start at the new seek position
1051 EXPECT_LE(seek_position, manager_.pts_stat_.min());
1052
1053 // The player should have reported the seek completion to the manager.
1054 EXPECT_TRUE(WaitForCondition(base::Bind(
1055 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
743 } 1056 }
744 1057
745 } // namespace media 1058 } // 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