OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "media/base/android/media_source_player.h" | 5 #include "media/base/android/media_source_player.h" |
6 | 6 |
| 7 #include <limits> |
| 8 |
7 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
8 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
9 #include "base/barrier_closure.h" | 11 #include "base/barrier_closure.h" |
10 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
11 #include "base/bind.h" | 13 #include "base/bind.h" |
12 #include "base/logging.h" | 14 #include "base/logging.h" |
13 #include "media/base/android/audio_decoder_job.h" | 15 #include "media/base/android/audio_decoder_job.h" |
14 #include "media/base/android/media_drm_bridge.h" | 16 #include "media/base/android/media_drm_bridge.h" |
15 #include "media/base/android/media_player_manager.h" | 17 #include "media/base/android/media_player_manager.h" |
16 #include "media/base/android/video_decoder_job.h" | 18 #include "media/base/android/video_decoder_job.h" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 pending_event_ = NO_EVENT_PENDING; | 180 pending_event_ = NO_EVENT_PENDING; |
179 surface_ = gfx::ScopedJavaSurface(); | 181 surface_ = gfx::ScopedJavaSurface(); |
180 ReleaseMediaResourcesFromManager(); | 182 ReleaseMediaResourcesFromManager(); |
181 } | 183 } |
182 | 184 |
183 void MediaSourcePlayer::SetVolume(double volume) { | 185 void MediaSourcePlayer::SetVolume(double volume) { |
184 volume_ = volume; | 186 volume_ = volume; |
185 SetVolumeInternal(); | 187 SetVolumeInternal(); |
186 } | 188 } |
187 | 189 |
| 190 void MediaSourcePlayer::OnKeyAdded() { |
| 191 DVLOG(1) << __FUNCTION__; |
| 192 if (playing_) |
| 193 StartInternal(); |
| 194 } |
| 195 |
188 bool MediaSourcePlayer::CanPause() { | 196 bool MediaSourcePlayer::CanPause() { |
189 return Seekable(); | 197 return Seekable(); |
190 } | 198 } |
191 | 199 |
192 bool MediaSourcePlayer::CanSeekForward() { | 200 bool MediaSourcePlayer::CanSeekForward() { |
193 return Seekable(); | 201 return Seekable(); |
194 } | 202 } |
195 | 203 |
196 bool MediaSourcePlayer::CanSeekBackward() { | 204 bool MediaSourcePlayer::CanSeekBackward() { |
197 return Seekable(); | 205 return Seekable(); |
198 } | 206 } |
199 | 207 |
200 bool MediaSourcePlayer::IsPlayerReady() { | 208 bool MediaSourcePlayer::IsPlayerReady() { |
201 return audio_decoder_job_ || video_decoder_job_; | 209 return audio_decoder_job_ || video_decoder_job_; |
202 } | 210 } |
203 | 211 |
204 void MediaSourcePlayer::StartInternal() { | 212 void MediaSourcePlayer::StartInternal() { |
205 DVLOG(1) << __FUNCTION__; | 213 DVLOG(1) << __FUNCTION__; |
206 // If there are pending events, wait for them finish. | 214 // If there are pending events, wait for them finish. |
207 if (pending_event_ != NO_EVENT_PENDING) | 215 if (pending_event_ != NO_EVENT_PENDING) |
208 return; | 216 return; |
209 | 217 |
210 // Create decoder jobs if they are not created | 218 // Create decoder jobs if they are not created |
211 ConfigureAudioDecoderJob(); | 219 ConfigureAudioDecoderJob(); |
212 ConfigureVideoDecoderJob(); | 220 ConfigureVideoDecoderJob(); |
213 | 221 |
214 | |
215 // If one of the decoder job is not ready, do nothing. | 222 // If one of the decoder job is not ready, do nothing. |
216 if ((HasAudio() && !audio_decoder_job_) || | 223 if ((HasAudio() && !audio_decoder_job_) || |
217 (HasVideo() && !video_decoder_job_)) { | 224 (HasVideo() && !video_decoder_job_)) { |
218 return; | 225 return; |
219 } | 226 } |
220 | 227 |
221 audio_finished_ = false; | 228 audio_finished_ = false; |
222 video_finished_ = false; | 229 video_finished_ = false; |
223 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 230 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
224 ProcessPendingEvents(); | 231 ProcessPendingEvents(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); | 346 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); |
340 clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp()); | 347 clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp()); |
341 } else { | 348 } else { |
342 clock_.SetMaxTime(presentation_timestamp); | 349 clock_.SetMaxTime(presentation_timestamp); |
343 } | 350 } |
344 | 351 |
345 OnTimeUpdated(); | 352 OnTimeUpdated(); |
346 } | 353 } |
347 | 354 |
348 void MediaSourcePlayer::ProcessPendingEvents() { | 355 void MediaSourcePlayer::ProcessPendingEvents() { |
349 DVLOG(1) << __FUNCTION__ << " : 0x" | 356 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; |
350 << std::hex << pending_event_; | |
351 // Wait for all the decoding jobs to finish before processing pending tasks. | 357 // Wait for all the decoding jobs to finish before processing pending tasks. |
352 if ((audio_decoder_job_ && audio_decoder_job_->is_decoding()) || | 358 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { |
353 (video_decoder_job_ && video_decoder_job_->is_decoding())) { | 359 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; |
354 DVLOG(1) << __FUNCTION__ << " : A job is still decoding."; | |
355 return; | 360 return; |
356 } | 361 } |
357 | 362 |
| 363 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { |
| 364 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; |
| 365 return; |
| 366 } |
| 367 |
358 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { | 368 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { |
359 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; | 369 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; |
360 return; | 370 return; |
361 } | 371 } |
362 | 372 |
363 if (IsEventPending(SEEK_EVENT_PENDING)) { | 373 if (IsEventPending(SEEK_EVENT_PENDING)) { |
364 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT."; | 374 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT."; |
365 ClearDecodingData(); | 375 ClearDecodingData(); |
366 manager()->OnMediaSeekRequest( | 376 manager()->OnMediaSeekRequest( |
367 player_id(), GetCurrentTime(), ++seek_request_id_); | 377 player_id(), GetCurrentTime(), ++seek_request_id_); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 415 |
406 // Now that all pending events have been handled, resume decoding if we are | 416 // Now that all pending events have been handled, resume decoding if we are |
407 // still playing. | 417 // still playing. |
408 if (playing_) | 418 if (playing_) |
409 StartInternal(); | 419 StartInternal(); |
410 } | 420 } |
411 | 421 |
412 void MediaSourcePlayer::MediaDecoderCallback( | 422 void MediaSourcePlayer::MediaDecoderCallback( |
413 bool is_audio, MediaCodecStatus status, | 423 bool is_audio, MediaCodecStatus status, |
414 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { | 424 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { |
415 DVLOG(1) << __FUNCTION__; | 425 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; |
416 if (is_audio) | 426 if (is_audio) |
417 decoder_starvation_callback_.Cancel(); | 427 decoder_starvation_callback_.Cancel(); |
418 | 428 |
419 if (status == MEDIA_CODEC_ERROR) { | 429 if (status == MEDIA_CODEC_ERROR) { |
420 Release(); | 430 Release(); |
421 OnMediaError(MEDIA_ERROR_DECODE); | 431 OnMediaError(MEDIA_ERROR_DECODE); |
422 return; | 432 return; |
423 } | 433 } |
424 | 434 |
425 if (pending_event_ != NO_EVENT_PENDING) { | 435 if (pending_event_ != NO_EVENT_PENDING) { |
426 ProcessPendingEvents(); | 436 ProcessPendingEvents(); |
427 return; | 437 return; |
428 } | 438 } |
429 | 439 |
430 if (status == MEDIA_CODEC_OK && (is_audio || !HasAudio())) { | 440 if (status == MEDIA_CODEC_OK && (is_audio || !HasAudio())) { |
431 UpdateTimestamps(presentation_timestamp, audio_output_bytes); | 441 UpdateTimestamps(presentation_timestamp, audio_output_bytes); |
432 } | 442 } |
433 | 443 |
434 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) { | 444 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) { |
435 PlaybackCompleted(is_audio); | 445 PlaybackCompleted(is_audio); |
436 return; | 446 return; |
437 } | 447 } |
438 | 448 |
439 if (!playing_) { | 449 if (!playing_) { |
440 if (is_audio || !HasAudio()) | 450 if (is_audio || !HasAudio()) |
441 clock_.Pause(); | 451 clock_.Pause(); |
442 return; | 452 return; |
443 } | 453 } |
444 | 454 |
| 455 if (status == MEDIA_CODEC_NO_KEY) |
| 456 return; |
| 457 |
445 base::TimeDelta current_timestamp = GetCurrentTime(); | 458 base::TimeDelta current_timestamp = GetCurrentTime(); |
446 if (is_audio) { | 459 if (is_audio) { |
447 if (status == MEDIA_CODEC_OK) { | 460 if (status == MEDIA_CODEC_OK) { |
448 base::TimeDelta timeout = | 461 base::TimeDelta timeout = |
449 audio_timestamp_helper_->GetTimestamp() - current_timestamp; | 462 audio_timestamp_helper_->GetTimestamp() - current_timestamp; |
450 StartStarvationCallback(timeout); | 463 StartStarvationCallback(timeout); |
451 } | 464 } |
452 DecodeMoreAudio(); | 465 DecodeMoreAudio(); |
453 return; | 466 return; |
454 } | 467 } |
455 | 468 |
456 if (!HasAudio() && status == MEDIA_CODEC_OK) { | 469 if (!HasAudio() && status == MEDIA_CODEC_OK) { |
457 DCHECK(current_timestamp <= presentation_timestamp); | 470 DCHECK(current_timestamp <= presentation_timestamp); |
458 // For video only streams, fps can be estimated from the difference | 471 // For video only streams, fps can be estimated from the difference |
459 // between the previous and current presentation timestamps. The | 472 // between the previous and current presentation timestamps. The |
460 // previous presentation timestamp is equal to current_timestamp. | 473 // previous presentation timestamp is equal to current_timestamp. |
461 // TODO(qinmin): determine whether 2 is a good coefficient for estimating | 474 // TODO(qinmin): determine whether 2 is a good coefficient for estimating |
462 // video frame timeout. | 475 // video frame timeout. |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 | 695 |
683 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 696 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
684 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 697 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
685 DCHECK_NE(event, NO_EVENT_PENDING); | 698 DCHECK_NE(event, NO_EVENT_PENDING); |
686 DCHECK(IsEventPending(event)); | 699 DCHECK(IsEventPending(event)); |
687 | 700 |
688 pending_event_ &= ~event; | 701 pending_event_ &= ~event; |
689 } | 702 } |
690 | 703 |
691 } // namespace media | 704 } // namespace media |
OLD | NEW |