OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/media/webmediaplayer_impl.h" | 5 #include "webkit/media/webmediaplayer_impl.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | |
9 | 10 |
10 #include "base/bind.h" | 11 #include "base/bind.h" |
11 #include "base/callback.h" | 12 #include "base/callback.h" |
12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
13 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
14 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
15 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
16 #include "base/synchronization/waitable_event.h" | 17 #include "base/synchronization/waitable_event.h" |
17 #include "media/audio/null_audio_sink.h" | 18 #include "media/audio/null_audio_sink.h" |
18 #include "media/base/filter_collection.h" | 19 #include "media/base/filter_collection.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 base::Bind(&WebMediaPlayerProxy::SetOpaque, proxy_.get()), | 151 base::Bind(&WebMediaPlayerProxy::SetOpaque, proxy_.get()), |
151 true); | 152 true); |
152 filter_collection_->AddVideoRenderer(video_renderer); | 153 filter_collection_->AddVideoRenderer(video_renderer); |
153 proxy_->set_frame_provider(video_renderer); | 154 proxy_->set_frame_provider(video_renderer); |
154 | 155 |
155 // Create default audio renderer. | 156 // Create default audio renderer. |
156 filter_collection_->AddAudioRenderer( | 157 filter_collection_->AddAudioRenderer( |
157 new media::AudioRendererImpl(new media::NullAudioSink())); | 158 new media::AudioRendererImpl(new media::NullAudioSink())); |
158 | 159 |
159 decryptor_.reset(new media::AesDecryptor()); | 160 decryptor_.reset(new media::AesDecryptor()); |
161 decryptor_->Init(proxy_.get()); | |
160 } | 162 } |
161 | 163 |
162 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 164 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
163 DCHECK_EQ(main_loop_, MessageLoop::current()); | 165 DCHECK_EQ(main_loop_, MessageLoop::current()); |
164 Destroy(); | 166 Destroy(); |
165 media_log_->AddEvent( | 167 media_log_->AddEvent( |
166 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 168 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
167 | 169 |
168 if (delegate_) | 170 if (delegate_) |
169 delegate_->PlayerGone(this); | 171 delegate_->PlayerGone(this); |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 bool WebMediaPlayerImpl::sourceAbort(const WebKit::WebString& id) { | 694 bool WebMediaPlayerImpl::sourceAbort(const WebKit::WebString& id) { |
693 proxy_->DemuxerAbort(id.utf8().data()); | 695 proxy_->DemuxerAbort(id.utf8().data()); |
694 return true; | 696 return true; |
695 } | 697 } |
696 | 698 |
697 void WebMediaPlayerImpl::sourceEndOfStream( | 699 void WebMediaPlayerImpl::sourceEndOfStream( |
698 WebMediaPlayer::EndOfStreamStatus status) { | 700 WebMediaPlayer::EndOfStreamStatus status) { |
699 DCHECK_EQ(main_loop_, MessageLoop::current()); | 701 DCHECK_EQ(main_loop_, MessageLoop::current()); |
700 media::PipelineStatus pipeline_status = media::PIPELINE_OK; | 702 media::PipelineStatus pipeline_status = media::PIPELINE_OK; |
701 | 703 |
702 switch(status) { | 704 switch (status) { |
703 case WebMediaPlayer::EndOfStreamStatusNoError: | 705 case WebMediaPlayer::EndOfStreamStatusNoError: |
704 break; | 706 break; |
705 case WebMediaPlayer::EndOfStreamStatusNetworkError: | 707 case WebMediaPlayer::EndOfStreamStatusNetworkError: |
706 pipeline_status = media::PIPELINE_ERROR_NETWORK; | 708 pipeline_status = media::PIPELINE_ERROR_NETWORK; |
707 break; | 709 break; |
708 case WebMediaPlayer::EndOfStreamStatusDecodeError: | 710 case WebMediaPlayer::EndOfStreamStatusDecodeError: |
709 pipeline_status = media::PIPELINE_ERROR_DECODE; | 711 pipeline_status = media::PIPELINE_ERROR_DECODE; |
710 break; | 712 break; |
711 default: | 713 default: |
712 NOTIMPLEMENTED(); | 714 NOTIMPLEMENTED(); |
713 } | 715 } |
714 | 716 |
715 proxy_->DemuxerEndOfStream(pipeline_status); | 717 proxy_->DemuxerEndOfStream(pipeline_status); |
716 } | 718 } |
717 | 719 |
718 WebKit::WebMediaPlayer::MediaKeyException | 720 WebKit::WebMediaPlayer::MediaKeyException |
719 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, | 721 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, |
720 const unsigned char* init_data, | 722 const unsigned char* init_data, |
721 unsigned init_data_length) { | 723 unsigned init_data_length) { |
722 if (!IsSupportedKeySystem(key_system)) | 724 if (!IsSupportedKeySystem(key_system)) |
723 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 725 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
724 | 726 |
725 // Every request call creates a unique ID. | |
726 // TODO(ddorwin): Move this to the CDM implementations since the CDMs may | |
727 // create their own IDs and since CDMs supporting multiple renderer processes | |
728 // need globally unique IDs. | |
729 // Everything from here until the return should probably be handled by | |
730 // the decryptor - see http://crbug.com/123260. | |
731 static uint32_t next_available_session_id = 1; | |
732 uint32_t session_id = next_available_session_id++; | |
733 | |
734 WebString session_id_string(base::UintToString16(session_id)); | |
735 | |
736 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " | 727 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " |
737 << std::string(reinterpret_cast<const char*>(init_data), | 728 << std::string(reinterpret_cast<const char*>(init_data), |
738 static_cast<size_t>(init_data_length)) | 729 static_cast<size_t>(init_data_length)); |
739 << " [" << session_id_string.utf8().data() << "]"; | |
740 | 730 |
741 // TODO(ddorwin): Generate a key request in the decryptor and fire | 731 decryptor_->GenerateKeyRequest(key_system.utf8(), |
ddorwin
2012/06/11 21:02:40
At some point, we will need to post these operatio
xhwang
2012/06/12 19:01:15
I suppose these key operations called on the rende
| |
742 // keyMessage when it completes. | 732 init_data, init_data_length); |
743 // For now, just fire the event with the init_data as the request. | |
744 const unsigned char* message = init_data; | |
745 unsigned message_length = init_data_length; | |
746 | |
747 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | |
748 &WebKit::WebMediaPlayerClient::keyMessage, | |
749 base::Unretained(GetClient()), | |
750 key_system, | |
751 session_id_string, | |
752 message, | |
753 message_length)); | |
754 | |
755 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; | 733 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
756 } | 734 } |
757 | 735 |
758 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( | 736 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( |
759 const WebString& key_system, | 737 const WebString& key_system, |
760 const unsigned char* key, | 738 const unsigned char* key, |
761 unsigned key_length, | 739 unsigned key_length, |
762 const unsigned char* init_data, | 740 const unsigned char* init_data, |
763 unsigned init_data_length, | 741 unsigned init_data_length, |
764 const WebString& session_id) { | 742 const WebString& session_id) { |
765 DCHECK(key); | 743 DCHECK(key); |
766 DCHECK_GT(key_length, 0u); | 744 DCHECK_GT(key_length, 0u); |
767 | 745 |
768 if (!IsSupportedKeySystem(key_system)) | 746 if (!IsSupportedKeySystem(key_system)) |
769 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 747 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
770 | 748 |
771 | |
772 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " | 749 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " |
773 << std::string(reinterpret_cast<const char*>(key), | 750 << std::string(reinterpret_cast<const char*>(key), |
774 static_cast<size_t>(key_length)) << ", " | 751 static_cast<size_t>(key_length)) << ", " |
775 << std::string(reinterpret_cast<const char*>(init_data), | 752 << std::string(reinterpret_cast<const char*>(init_data), |
776 static_cast<size_t>(init_data_length)) | 753 static_cast<size_t>(init_data_length)) |
777 << " [" << session_id.utf8().data() << "]"; | 754 << " [" << session_id.utf8().data() << "]"; |
778 | 755 |
779 // TODO(ddorwin): Everything from here until the return should probably be | 756 decryptor_->AddKey(key_system.utf8(), init_data, init_data_length, |
780 // handled by the decryptor - see http://crbug.com/123260. | 757 key, key_length, session_id.utf8()); |
781 // Temporarily, fire an error for invalid key length so we can test the error | |
782 // event and fire the keyAdded event in all other cases. | |
783 const unsigned kSupportedKeyLength = 16; // 128-bit key. | |
784 if (key_length != kSupportedKeyLength) { | |
785 DLOG(ERROR) << "addKey: invalid key length: " << key_length; | |
786 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | |
787 &WebKit::WebMediaPlayerClient::keyError, | |
788 base::Unretained(GetClient()), | |
789 key_system, | |
790 session_id, | |
791 WebKit::WebMediaPlayerClient::MediaKeyErrorCodeUnknown, | |
792 0)); | |
793 } else { | |
794 // TODO(ddorwin): Fix the decryptor to accept no |init_data|. See | |
795 // http://crbug.com/123265. Until then, ensure a non-empty value is passed. | |
796 static const unsigned char kDummyInitData[1] = {0}; | |
797 if (!init_data) { | |
798 init_data = kDummyInitData; | |
799 init_data_length = arraysize(kDummyInitData); | |
800 } | |
801 | |
802 decryptor_->AddKey(init_data, init_data_length, key, key_length); | |
803 | |
804 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | |
805 &WebKit::WebMediaPlayerClient::keyAdded, | |
806 base::Unretained(GetClient()), | |
807 key_system, | |
808 session_id)); | |
809 } | |
810 | |
811 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; | 758 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
812 } | 759 } |
813 | 760 |
814 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( | 761 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( |
815 const WebString& key_system, | 762 const WebString& key_system, |
816 const WebString& session_id) { | 763 const WebString& session_id) { |
817 if (!IsSupportedKeySystem(key_system)) | 764 if (!IsSupportedKeySystem(key_system)) |
818 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 765 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
819 | 766 |
820 // TODO(ddorwin): Cancel the key request in the decryptor. | 767 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); |
821 | |
822 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; | 768 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
823 } | 769 } |
824 | 770 |
825 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { | 771 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { |
826 Destroy(); | 772 Destroy(); |
827 main_loop_ = NULL; | 773 main_loop_ = NULL; |
828 } | 774 } |
829 | 775 |
830 void WebMediaPlayerImpl::Repaint() { | 776 void WebMediaPlayerImpl::Repaint() { |
831 DCHECK_EQ(main_loop_, MessageLoop::current()); | 777 DCHECK_EQ(main_loop_, MessageLoop::current()); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
924 SetNetworkState(WebMediaPlayer::NetworkStateDecodeError); | 870 SetNetworkState(WebMediaPlayer::NetworkStateDecodeError); |
925 break; | 871 break; |
926 } | 872 } |
927 | 873 |
928 // Repaint to trigger UI update. | 874 // Repaint to trigger UI update. |
929 Repaint(); | 875 Repaint(); |
930 } | 876 } |
931 | 877 |
932 void WebMediaPlayerImpl::OnNetworkEvent(NetworkEvent type) { | 878 void WebMediaPlayerImpl::OnNetworkEvent(NetworkEvent type) { |
933 DCHECK_EQ(main_loop_, MessageLoop::current()); | 879 DCHECK_EQ(main_loop_, MessageLoop::current()); |
934 switch(type) { | 880 switch (type) { |
935 case media::DOWNLOAD_CONTINUED: | 881 case media::DOWNLOAD_CONTINUED: |
936 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 882 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
937 break; | 883 break; |
938 case media::DOWNLOAD_PAUSED: | 884 case media::DOWNLOAD_PAUSED: |
939 SetNetworkState(WebMediaPlayer::NetworkStateIdle); | 885 SetNetworkState(WebMediaPlayer::NetworkStateIdle); |
940 break; | 886 break; |
941 case media::CAN_PLAY_THROUGH: | 887 case media::CAN_PLAY_THROUGH: |
942 // Temporarily disable delayed firing of CAN_PLAY_THROUGH due to | 888 // Temporarily disable delayed firing of CAN_PLAY_THROUGH due to |
943 // crbug.com/106480. | 889 // crbug.com/106480. |
944 // TODO(vrk): uncomment code below when bug above is fixed. | 890 // TODO(vrk): uncomment code below when bug above is fixed. |
945 // SetReadyState(WebMediaPlayer::NetworkStateHaveEnoughData); | 891 // SetReadyState(WebMediaPlayer::NetworkStateHaveEnoughData); |
946 break; | 892 break; |
947 default: | 893 default: |
948 NOTREACHED(); | 894 NOTREACHED(); |
949 } | 895 } |
950 } | 896 } |
951 | 897 |
952 void WebMediaPlayerImpl::OnDemuxerOpened() { | 898 void WebMediaPlayerImpl::OnDemuxerOpened() { |
953 DCHECK_EQ(main_loop_, MessageLoop::current()); | 899 DCHECK_EQ(main_loop_, MessageLoop::current()); |
954 | 900 |
955 GetClient()->sourceOpened(); | 901 GetClient()->sourceOpened(); |
956 } | 902 } |
957 | 903 |
958 void WebMediaPlayerImpl::OnKeyNeeded(scoped_array<uint8> init_data, | 904 void WebMediaPlayerImpl::OnKeyAdded(const std::string& key_system, |
905 const std::string& session_id) { | |
906 DCHECK_EQ(main_loop_, MessageLoop::current()); | |
907 | |
908 GetClient()->keyAdded(WebString::fromUTF8(key_system), | |
909 WebString::fromUTF8(session_id)); | |
910 } | |
911 | |
912 void WebMediaPlayerImpl::OnKeyNeeded(const std::string& key_system, | |
913 const std::string& session_id, | |
914 scoped_array<uint8> init_data, | |
959 int init_data_size) { | 915 int init_data_size) { |
960 DCHECK_EQ(main_loop_, MessageLoop::current()); | 916 DCHECK_EQ(main_loop_, MessageLoop::current()); |
961 | 917 |
962 GetClient()->keyNeeded("", "", init_data.get(), init_data_size); | 918 GetClient()->keyNeeded(WebString::fromUTF8(key_system), |
919 WebString::fromUTF8(session_id), | |
920 init_data.get(), | |
921 init_data_size); | |
922 } | |
923 | |
924 void WebMediaPlayerImpl::OnKeyError(const std::string& key_system, | |
925 const std::string& session_id, | |
926 media::AesDecryptor::KeyError error_code, | |
927 int system_code) { | |
928 DCHECK_EQ(main_loop_, MessageLoop::current()); | |
929 | |
930 GetClient()->keyError( | |
931 WebString::fromUTF8(key_system), | |
932 WebString::fromUTF8(session_id), | |
933 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code), | |
934 system_code); | |
935 } | |
936 | |
937 void WebMediaPlayerImpl::OnKeyMessage(const std::string& key_system, | |
938 const std::string& session_id, | |
939 scoped_array<uint8> message, | |
940 int message_length, | |
941 const std::string& /* default_url */) { | |
942 DCHECK_EQ(main_loop_, MessageLoop::current()); | |
943 | |
944 GetClient()->keyMessage(WebString::fromUTF8(key_system), | |
945 WebString::fromUTF8(session_id), | |
946 message.get(), | |
947 message_length); | |
963 } | 948 } |
964 | 949 |
965 void WebMediaPlayerImpl::SetOpaque(bool opaque) { | 950 void WebMediaPlayerImpl::SetOpaque(bool opaque) { |
966 DCHECK_EQ(main_loop_, MessageLoop::current()); | 951 DCHECK_EQ(main_loop_, MessageLoop::current()); |
967 | 952 |
968 GetClient()->setOpaque(opaque); | 953 GetClient()->setOpaque(opaque); |
969 } | 954 } |
970 | 955 |
971 void WebMediaPlayerImpl::DataSourceInitialized( | 956 void WebMediaPlayerImpl::DataSourceInitialized( |
972 const GURL& gurl, | 957 const GURL& gurl, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 return audio_source_provider_; | 1041 return audio_source_provider_; |
1057 } | 1042 } |
1058 | 1043 |
1059 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 1044 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
1060 DCHECK_EQ(main_loop_, MessageLoop::current()); | 1045 DCHECK_EQ(main_loop_, MessageLoop::current()); |
1061 incremented_externally_allocated_memory_ = true; | 1046 incremented_externally_allocated_memory_ = true; |
1062 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 1047 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |
1063 } | 1048 } |
1064 | 1049 |
1065 } // namespace webkit_media | 1050 } // namespace webkit_media |
OLD | NEW |