| 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 |