OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |