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> | 7 #include <limits> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 } | 30 } |
31 | 31 |
32 namespace media { | 32 namespace media { |
33 | 33 |
34 MediaSourcePlayer::MediaSourcePlayer( | 34 MediaSourcePlayer::MediaSourcePlayer( |
35 int player_id, | 35 int player_id, |
36 MediaPlayerManager* manager, | 36 MediaPlayerManager* manager, |
37 const RequestMediaResourcesCB& request_media_resources_cb, | 37 const RequestMediaResourcesCB& request_media_resources_cb, |
38 const ReleaseMediaResourcesCB& release_media_resources_cb, | 38 const ReleaseMediaResourcesCB& release_media_resources_cb, |
39 scoped_ptr<DemuxerAndroid> demuxer) | 39 scoped_ptr<DemuxerAndroid> demuxer) |
40 : MediaPlayerAndroid(player_id, manager, request_media_resources_cb, | 40 : MediaPlayerAndroid(player_id, |
| 41 manager, |
| 42 request_media_resources_cb, |
41 release_media_resources_cb), | 43 release_media_resources_cb), |
42 demuxer_(demuxer.Pass()), | 44 demuxer_(demuxer.Pass()), |
43 pending_event_(NO_EVENT_PENDING), | 45 pending_event_(NO_EVENT_PENDING), |
44 width_(0), | 46 width_(0), |
45 height_(0), | 47 height_(0), |
46 audio_codec_(kUnknownAudioCodec), | 48 audio_codec_(kUnknownAudioCodec), |
47 video_codec_(kUnknownVideoCodec), | 49 video_codec_(kUnknownVideoCodec), |
48 num_channels_(0), | 50 num_channels_(0), |
49 sampling_rate_(0), | 51 sampling_rate_(0), |
50 reached_audio_eos_(false), | 52 reached_audio_eos_(false), |
51 reached_video_eos_(false), | 53 reached_video_eos_(false), |
52 playing_(false), | 54 playing_(false), |
53 is_audio_encrypted_(false), | 55 is_audio_encrypted_(false), |
54 is_video_encrypted_(false), | 56 is_video_encrypted_(false), |
55 volume_(-1.0), | 57 volume_(-1.0), |
56 clock_(&default_tick_clock_), | 58 clock_(&default_tick_clock_), |
57 next_video_data_is_iframe_(true), | 59 next_video_data_is_iframe_(true), |
58 doing_browser_seek_(false), | 60 doing_browser_seek_(false), |
59 pending_seek_(false), | 61 pending_seek_(false), |
60 reconfig_audio_decoder_(false), | 62 reconfig_audio_decoder_(false), |
61 reconfig_video_decoder_(false), | 63 reconfig_video_decoder_(false), |
62 weak_this_(this), | |
63 drm_bridge_(NULL), | 64 drm_bridge_(NULL), |
64 is_waiting_for_key_(false) { | 65 is_waiting_for_key_(false), |
| 66 weak_factory_(this) { |
65 demuxer_->Initialize(this); | 67 demuxer_->Initialize(this); |
66 clock_.SetMaxTime(base::TimeDelta()); | 68 clock_.SetMaxTime(base::TimeDelta()); |
67 } | 69 } |
68 | 70 |
69 MediaSourcePlayer::~MediaSourcePlayer() { | 71 MediaSourcePlayer::~MediaSourcePlayer() { |
70 Release(); | 72 Release(); |
71 } | 73 } |
72 | 74 |
73 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 75 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
74 // For an empty surface, always pass it to the decoder job so that it | 76 // For an empty surface, always pass it to the decoder job so that it |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 // http://crbug.com/253792. | 383 // http://crbug.com/253792. |
382 if (GetCurrentTime() > base::TimeDelta()) { | 384 if (GetCurrentTime() > base::TimeDelta()) { |
383 VLOG(0) << "Setting DRM bridge after playback has started. " | 385 VLOG(0) << "Setting DRM bridge after playback has started. " |
384 << "This is not well supported!"; | 386 << "This is not well supported!"; |
385 } | 387 } |
386 | 388 |
387 drm_bridge_ = drm_bridge; | 389 drm_bridge_ = drm_bridge; |
388 | 390 |
389 if (drm_bridge_->GetMediaCrypto().is_null()) { | 391 if (drm_bridge_->GetMediaCrypto().is_null()) { |
390 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( | 392 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( |
391 &MediaSourcePlayer::OnMediaCryptoReady, weak_this_.GetWeakPtr())); | 393 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); |
392 return; | 394 return; |
393 } | 395 } |
394 | 396 |
395 if (playing_) | 397 if (playing_) |
396 StartInternal(); | 398 StartInternal(); |
397 } | 399 } |
398 | 400 |
399 void MediaSourcePlayer::OnDemuxerSeekDone( | 401 void MediaSourcePlayer::OnDemuxerSeekDone( |
400 const base::TimeDelta& actual_browser_seek_time) { | 402 const base::TimeDelta& actual_browser_seek_time) { |
401 DVLOG(1) << __FUNCTION__; | 403 DVLOG(1) << __FUNCTION__; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); | 518 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); |
517 | 519 |
518 // It is possible that all streams have finished decode, yet starvation | 520 // It is possible that all streams have finished decode, yet starvation |
519 // occurred during the last stream's EOS decode. In this case, prefetch is a | 521 // occurred during the last stream's EOS decode. In this case, prefetch is a |
520 // no-op. | 522 // no-op. |
521 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); | 523 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); |
522 if (count == 0) | 524 if (count == 0) |
523 return; | 525 return; |
524 | 526 |
525 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); | 527 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); |
526 base::Closure barrier = BarrierClosure(count, base::Bind( | 528 base::Closure barrier = |
527 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr())); | 529 BarrierClosure(count, |
| 530 base::Bind(&MediaSourcePlayer::OnPrefetchDone, |
| 531 weak_factory_.GetWeakPtr())); |
528 | 532 |
529 if (!AudioFinished()) | 533 if (!AudioFinished()) |
530 audio_decoder_job_->Prefetch(barrier); | 534 audio_decoder_job_->Prefetch(barrier); |
531 | 535 |
532 if (!VideoFinished()) | 536 if (!VideoFinished()) |
533 video_decoder_job_->Prefetch(barrier); | 537 video_decoder_job_->Prefetch(barrier); |
534 | 538 |
535 return; | 539 return; |
536 } | 540 } |
537 | 541 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 | 643 |
640 DecodeMoreVideo(); | 644 DecodeMoreVideo(); |
641 } | 645 } |
642 | 646 |
643 void MediaSourcePlayer::DecodeMoreAudio() { | 647 void MediaSourcePlayer::DecodeMoreAudio() { |
644 DVLOG(1) << __FUNCTION__; | 648 DVLOG(1) << __FUNCTION__; |
645 DCHECK(!audio_decoder_job_->is_decoding()); | 649 DCHECK(!audio_decoder_job_->is_decoding()); |
646 DCHECK(!AudioFinished()); | 650 DCHECK(!AudioFinished()); |
647 | 651 |
648 if (audio_decoder_job_->Decode( | 652 if (audio_decoder_job_->Decode( |
649 start_time_ticks_, start_presentation_timestamp_, base::Bind( | 653 start_time_ticks_, |
650 &MediaSourcePlayer::MediaDecoderCallback, | 654 start_presentation_timestamp_, |
651 weak_this_.GetWeakPtr(), true))) { | 655 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| 656 weak_factory_.GetWeakPtr(), |
| 657 true))) { |
652 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", | 658 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", |
653 audio_decoder_job_.get()); | 659 audio_decoder_job_.get()); |
654 return; | 660 return; |
655 } | 661 } |
656 | 662 |
657 // Failed to start the next decode. | 663 // Failed to start the next decode. |
658 // Wait for demuxer ready message. | 664 // Wait for demuxer ready message. |
659 DCHECK(!reconfig_audio_decoder_); | 665 DCHECK(!reconfig_audio_decoder_); |
660 reconfig_audio_decoder_ = true; | 666 reconfig_audio_decoder_ = true; |
661 | 667 |
662 // Config change may have just been detected on the other stream. If so, | 668 // Config change may have just been detected on the other stream. If so, |
663 // don't send a duplicate demuxer config request. | 669 // don't send a duplicate demuxer config request. |
664 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { | 670 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { |
665 DCHECK(reconfig_video_decoder_); | 671 DCHECK(reconfig_video_decoder_); |
666 return; | 672 return; |
667 } | 673 } |
668 | 674 |
669 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); | 675 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); |
670 ProcessPendingEvents(); | 676 ProcessPendingEvents(); |
671 } | 677 } |
672 | 678 |
673 void MediaSourcePlayer::DecodeMoreVideo() { | 679 void MediaSourcePlayer::DecodeMoreVideo() { |
674 DVLOG(1) << __FUNCTION__; | 680 DVLOG(1) << __FUNCTION__; |
675 DCHECK(!video_decoder_job_->is_decoding()); | 681 DCHECK(!video_decoder_job_->is_decoding()); |
676 DCHECK(!VideoFinished()); | 682 DCHECK(!VideoFinished()); |
677 | 683 |
678 if (video_decoder_job_->Decode( | 684 if (video_decoder_job_->Decode( |
679 start_time_ticks_, start_presentation_timestamp_, base::Bind( | 685 start_time_ticks_, |
680 &MediaSourcePlayer::MediaDecoderCallback, | 686 start_presentation_timestamp_, |
681 weak_this_.GetWeakPtr(), false))) { | 687 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, |
| 688 weak_factory_.GetWeakPtr(), |
| 689 false))) { |
682 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", | 690 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", |
683 video_decoder_job_.get()); | 691 video_decoder_job_.get()); |
684 return; | 692 return; |
685 } | 693 } |
686 | 694 |
687 // Failed to start the next decode. | 695 // Failed to start the next decode. |
688 // Wait for demuxer ready message. | 696 // Wait for demuxer ready message. |
689 | 697 |
690 // After this detection of video config change, next video data received | 698 // After this detection of video config change, next video data received |
691 // will begin with I-frame. | 699 // will begin with I-frame. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 // For video only streams, fps can be estimated from the difference | 885 // For video only streams, fps can be estimated from the difference |
878 // between the previous and current presentation timestamps. The | 886 // between the previous and current presentation timestamps. The |
879 // previous presentation timestamp is equal to current_timestamp. | 887 // previous presentation timestamp is equal to current_timestamp. |
880 // TODO(qinmin): determine whether 2 is a good coefficient for estimating | 888 // TODO(qinmin): determine whether 2 is a good coefficient for estimating |
881 // video frame timeout. | 889 // video frame timeout. |
882 timeout = 2 * (presentation_timestamp - current_timestamp); | 890 timeout = 2 * (presentation_timestamp - current_timestamp); |
883 } | 891 } |
884 | 892 |
885 timeout = std::max(timeout, kMinStarvationTimeout); | 893 timeout = std::max(timeout, kMinStarvationTimeout); |
886 | 894 |
887 decoder_starvation_callback_.Reset( | 895 decoder_starvation_callback_.Reset(base::Bind( |
888 base::Bind(&MediaSourcePlayer::OnDecoderStarved, | 896 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); |
889 weak_this_.GetWeakPtr())); | |
890 base::MessageLoop::current()->PostDelayedTask( | 897 base::MessageLoop::current()->PostDelayedTask( |
891 FROM_HERE, decoder_starvation_callback_.callback(), timeout); | 898 FROM_HERE, decoder_starvation_callback_.callback(), timeout); |
892 } | 899 } |
893 | 900 |
894 void MediaSourcePlayer::SetVolumeInternal() { | 901 void MediaSourcePlayer::SetVolumeInternal() { |
895 if (audio_decoder_job_ && volume_ >= 0) | 902 if (audio_decoder_job_ && volume_ >= 0) |
896 audio_decoder_job_->SetVolume(volume_); | 903 audio_decoder_job_->SetVolume(volume_); |
897 } | 904 } |
898 | 905 |
899 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { | 906 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 | 975 |
969 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { | 976 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { |
970 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; | 977 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; |
971 DCHECK_NE(event, NO_EVENT_PENDING); | 978 DCHECK_NE(event, NO_EVENT_PENDING); |
972 DCHECK(IsEventPending(event)) << GetEventName(event); | 979 DCHECK(IsEventPending(event)) << GetEventName(event); |
973 | 980 |
974 pending_event_ &= ~event; | 981 pending_event_ &= ~event; |
975 } | 982 } |
976 | 983 |
977 } // namespace media | 984 } // namespace media |
OLD | NEW |