| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 base::Bind(&WebMediaPlayerProxy::Repaint, proxy_), | 150 base::Bind(&WebMediaPlayerProxy::Repaint, proxy_), |
| 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(proxy_.get())); |
| 160 } | 161 } |
| 161 | 162 |
| 162 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 163 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
| 163 DCHECK_EQ(main_loop_, MessageLoop::current()); | 164 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 164 Destroy(); | 165 Destroy(); |
| 165 media_log_->AddEvent( | 166 media_log_->AddEvent( |
| 166 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 167 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
| 167 | 168 |
| 168 if (delegate_) | 169 if (delegate_) |
| 169 delegate_->PlayerGone(this); | 170 delegate_->PlayerGone(this); |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 bool WebMediaPlayerImpl::sourceAbort(const WebKit::WebString& id) { | 693 bool WebMediaPlayerImpl::sourceAbort(const WebKit::WebString& id) { |
| 693 proxy_->DemuxerAbort(id.utf8().data()); | 694 proxy_->DemuxerAbort(id.utf8().data()); |
| 694 return true; | 695 return true; |
| 695 } | 696 } |
| 696 | 697 |
| 697 void WebMediaPlayerImpl::sourceEndOfStream( | 698 void WebMediaPlayerImpl::sourceEndOfStream( |
| 698 WebMediaPlayer::EndOfStreamStatus status) { | 699 WebMediaPlayer::EndOfStreamStatus status) { |
| 699 DCHECK_EQ(main_loop_, MessageLoop::current()); | 700 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 700 media::PipelineStatus pipeline_status = media::PIPELINE_OK; | 701 media::PipelineStatus pipeline_status = media::PIPELINE_OK; |
| 701 | 702 |
| 702 switch(status) { | 703 switch (status) { |
| 703 case WebMediaPlayer::EndOfStreamStatusNoError: | 704 case WebMediaPlayer::EndOfStreamStatusNoError: |
| 704 break; | 705 break; |
| 705 case WebMediaPlayer::EndOfStreamStatusNetworkError: | 706 case WebMediaPlayer::EndOfStreamStatusNetworkError: |
| 706 pipeline_status = media::PIPELINE_ERROR_NETWORK; | 707 pipeline_status = media::PIPELINE_ERROR_NETWORK; |
| 707 break; | 708 break; |
| 708 case WebMediaPlayer::EndOfStreamStatusDecodeError: | 709 case WebMediaPlayer::EndOfStreamStatusDecodeError: |
| 709 pipeline_status = media::PIPELINE_ERROR_DECODE; | 710 pipeline_status = media::PIPELINE_ERROR_DECODE; |
| 710 break; | 711 break; |
| 711 default: | 712 default: |
| 712 NOTIMPLEMENTED(); | 713 NOTIMPLEMENTED(); |
| 713 } | 714 } |
| 714 | 715 |
| 715 proxy_->DemuxerEndOfStream(pipeline_status); | 716 proxy_->DemuxerEndOfStream(pipeline_status); |
| 716 } | 717 } |
| 717 | 718 |
| 718 WebKit::WebMediaPlayer::MediaKeyException | 719 WebKit::WebMediaPlayer::MediaKeyException |
| 719 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, | 720 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, |
| 720 const unsigned char* init_data, | 721 const unsigned char* init_data, |
| 721 unsigned init_data_length) { | 722 unsigned init_data_length) { |
| 722 if (!IsSupportedKeySystem(key_system)) | 723 if (!IsSupportedKeySystem(key_system)) |
| 723 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 724 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 724 | 725 |
| 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() << ": " | 726 DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " |
| 737 << std::string(reinterpret_cast<const char*>(init_data), | 727 << std::string(reinterpret_cast<const char*>(init_data), |
| 738 static_cast<size_t>(init_data_length)) | 728 static_cast<size_t>(init_data_length)); |
| 739 << " [" << session_id_string.utf8().data() << "]"; | |
| 740 | 729 |
| 741 // TODO(ddorwin): Generate a key request in the decryptor and fire | 730 decryptor_->GenerateKeyRequest(key_system.utf8(), |
| 742 // keyMessage when it completes. | 731 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; | 732 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
| 756 } | 733 } |
| 757 | 734 |
| 758 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( | 735 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( |
| 759 const WebString& key_system, | 736 const WebString& key_system, |
| 760 const unsigned char* key, | 737 const unsigned char* key, |
| 761 unsigned key_length, | 738 unsigned key_length, |
| 762 const unsigned char* init_data, | 739 const unsigned char* init_data, |
| 763 unsigned init_data_length, | 740 unsigned init_data_length, |
| 764 const WebString& session_id) { | 741 const WebString& session_id) { |
| 765 DCHECK(key); | 742 DCHECK(key); |
| 766 DCHECK_GT(key_length, 0u); | 743 DCHECK_GT(key_length, 0u); |
| 767 | 744 |
| 768 if (!IsSupportedKeySystem(key_system)) | 745 if (!IsSupportedKeySystem(key_system)) |
| 769 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 746 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 770 | 747 |
| 771 | |
| 772 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " | 748 DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " |
| 773 << std::string(reinterpret_cast<const char*>(key), | 749 << std::string(reinterpret_cast<const char*>(key), |
| 774 static_cast<size_t>(key_length)) << ", " | 750 static_cast<size_t>(key_length)) << ", " |
| 775 << std::string(reinterpret_cast<const char*>(init_data), | 751 << std::string(reinterpret_cast<const char*>(init_data), |
| 776 static_cast<size_t>(init_data_length)) | 752 static_cast<size_t>(init_data_length)) |
| 777 << " [" << session_id.utf8().data() << "]"; | 753 << " [" << session_id.utf8().data() << "]"; |
| 778 | 754 |
| 779 // TODO(ddorwin): Everything from here until the return should probably be | 755 decryptor_->AddKey(key_system.utf8(), key, key_length, |
| 780 // handled by the decryptor - see http://crbug.com/123260. | 756 init_data, init_data_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; | 757 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
| 812 } | 758 } |
| 813 | 759 |
| 814 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( | 760 WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( |
| 815 const WebString& key_system, | 761 const WebString& key_system, |
| 816 const WebString& session_id) { | 762 const WebString& session_id) { |
| 817 if (!IsSupportedKeySystem(key_system)) | 763 if (!IsSupportedKeySystem(key_system)) |
| 818 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 764 return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 819 | 765 |
| 820 // TODO(ddorwin): Cancel the key request in the decryptor. | 766 decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); |
| 821 | |
| 822 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; | 767 return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; |
| 823 } | 768 } |
| 824 | 769 |
| 825 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { | 770 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { |
| 826 Destroy(); | 771 Destroy(); |
| 827 main_loop_ = NULL; | 772 main_loop_ = NULL; |
| 828 } | 773 } |
| 829 | 774 |
| 830 void WebMediaPlayerImpl::Repaint() { | 775 void WebMediaPlayerImpl::Repaint() { |
| 831 DCHECK_EQ(main_loop_, MessageLoop::current()); | 776 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 SetNetworkState(WebMediaPlayer::NetworkStateDecodeError); | 869 SetNetworkState(WebMediaPlayer::NetworkStateDecodeError); |
| 925 break; | 870 break; |
| 926 } | 871 } |
| 927 | 872 |
| 928 // Repaint to trigger UI update. | 873 // Repaint to trigger UI update. |
| 929 Repaint(); | 874 Repaint(); |
| 930 } | 875 } |
| 931 | 876 |
| 932 void WebMediaPlayerImpl::OnNetworkEvent(NetworkEvent type) { | 877 void WebMediaPlayerImpl::OnNetworkEvent(NetworkEvent type) { |
| 933 DCHECK_EQ(main_loop_, MessageLoop::current()); | 878 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 934 switch(type) { | 879 switch (type) { |
| 935 case media::DOWNLOAD_CONTINUED: | 880 case media::DOWNLOAD_CONTINUED: |
| 936 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 881 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 937 break; | 882 break; |
| 938 case media::DOWNLOAD_PAUSED: | 883 case media::DOWNLOAD_PAUSED: |
| 939 SetNetworkState(WebMediaPlayer::NetworkStateIdle); | 884 SetNetworkState(WebMediaPlayer::NetworkStateIdle); |
| 940 break; | 885 break; |
| 941 case media::CAN_PLAY_THROUGH: | 886 case media::CAN_PLAY_THROUGH: |
| 942 // Temporarily disable delayed firing of CAN_PLAY_THROUGH due to | 887 // Temporarily disable delayed firing of CAN_PLAY_THROUGH due to |
| 943 // crbug.com/106480. | 888 // crbug.com/106480. |
| 944 // TODO(vrk): uncomment code below when bug above is fixed. | 889 // TODO(vrk): uncomment code below when bug above is fixed. |
| 945 // SetReadyState(WebMediaPlayer::NetworkStateHaveEnoughData); | 890 // SetReadyState(WebMediaPlayer::NetworkStateHaveEnoughData); |
| 946 break; | 891 break; |
| 947 default: | 892 default: |
| 948 NOTREACHED(); | 893 NOTREACHED(); |
| 949 } | 894 } |
| 950 } | 895 } |
| 951 | 896 |
| 952 void WebMediaPlayerImpl::OnDemuxerOpened() { | 897 void WebMediaPlayerImpl::OnDemuxerOpened() { |
| 953 DCHECK_EQ(main_loop_, MessageLoop::current()); | 898 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 954 | 899 |
| 955 GetClient()->sourceOpened(); | 900 GetClient()->sourceOpened(); |
| 956 } | 901 } |
| 957 | 902 |
| 958 void WebMediaPlayerImpl::OnKeyNeeded(scoped_array<uint8> init_data, | 903 void WebMediaPlayerImpl::OnKeyAdded(const std::string& key_system, |
| 959 int init_data_size) { | 904 const std::string& session_id) { |
| 960 DCHECK_EQ(main_loop_, MessageLoop::current()); | 905 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 961 | 906 |
| 962 GetClient()->keyNeeded("", "", init_data.get(), init_data_size); | 907 GetClient()->keyAdded(WebString::fromUTF8(key_system), |
| 908 WebString::fromUTF8(session_id)); |
| 909 } |
| 910 |
| 911 void WebMediaPlayerImpl::OnNeedKey(const std::string& key_system, |
| 912 const std::string& session_id, |
| 913 scoped_array<uint8> init_data, |
| 914 int init_data_size) { |
| 915 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 916 |
| 917 GetClient()->keyNeeded(WebString::fromUTF8(key_system), |
| 918 WebString::fromUTF8(session_id), |
| 919 init_data.get(), |
| 920 init_data_size); |
| 921 } |
| 922 |
| 923 void WebMediaPlayerImpl::OnKeyError(const std::string& key_system, |
| 924 const std::string& session_id, |
| 925 media::AesDecryptor::KeyError error_code, |
| 926 int system_code) { |
| 927 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 928 |
| 929 GetClient()->keyError( |
| 930 WebString::fromUTF8(key_system), |
| 931 WebString::fromUTF8(session_id), |
| 932 static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code), |
| 933 system_code); |
| 934 } |
| 935 |
| 936 void WebMediaPlayerImpl::OnKeyMessage(const std::string& key_system, |
| 937 const std::string& session_id, |
| 938 scoped_array<uint8> message, |
| 939 int message_length, |
| 940 const std::string& /* default_url */) { |
| 941 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 942 |
| 943 GetClient()->keyMessage(WebString::fromUTF8(key_system), |
| 944 WebString::fromUTF8(session_id), |
| 945 message.get(), |
| 946 message_length); |
| 963 } | 947 } |
| 964 | 948 |
| 965 void WebMediaPlayerImpl::SetOpaque(bool opaque) { | 949 void WebMediaPlayerImpl::SetOpaque(bool opaque) { |
| 966 DCHECK_EQ(main_loop_, MessageLoop::current()); | 950 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 967 | 951 |
| 968 GetClient()->setOpaque(opaque); | 952 GetClient()->setOpaque(opaque); |
| 969 } | 953 } |
| 970 | 954 |
| 971 void WebMediaPlayerImpl::DataSourceInitialized( | 955 void WebMediaPlayerImpl::DataSourceInitialized( |
| 972 const GURL& gurl, | 956 const GURL& gurl, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 return audio_source_provider_; | 1040 return audio_source_provider_; |
| 1057 } | 1041 } |
| 1058 | 1042 |
| 1059 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 1043 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
| 1060 DCHECK_EQ(main_loop_, MessageLoop::current()); | 1044 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 1061 incremented_externally_allocated_memory_ = true; | 1045 incremented_externally_allocated_memory_ = true; |
| 1062 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 1046 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |
| 1063 } | 1047 } |
| 1064 | 1048 |
| 1065 } // namespace webkit_media | 1049 } // namespace webkit_media |
| OLD | NEW |