Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "content/renderer/media/android/webmediaplayer_android.h" | 5 #include "content/renderer/media/android/webmediaplayer_android.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 media_permission_(params.media_permission()), | 179 media_permission_(params.media_permission()), |
| 180 network_state_(WebMediaPlayer::NetworkStateEmpty), | 180 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 181 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 181 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 182 texture_id_(0), | 182 texture_id_(0), |
| 183 stream_id_(0), | 183 stream_id_(0), |
| 184 is_player_initialized_(false), | 184 is_player_initialized_(false), |
| 185 is_playing_(false), | 185 is_playing_(false), |
| 186 needs_establish_peer_(true), | 186 needs_establish_peer_(true), |
| 187 has_size_info_(false), | 187 has_size_info_(false), |
| 188 // Threaded compositing isn't enabled universally yet. | 188 // Threaded compositing isn't enabled universally yet. |
| 189 compositor_task_runner_( | 189 compositor_task_runner_(params.compositor_task_runner() |
| 190 params.compositor_task_runner() | 190 ? params.compositor_task_runner() |
| 191 ? params.compositor_task_runner() | 191 : base::ThreadTaskRunnerHandle::Get()), |
| 192 : base::ThreadTaskRunnerHandle::Get()), | |
| 193 stream_texture_factory_(factory), | 192 stream_texture_factory_(factory), |
| 194 needs_external_surface_(false), | 193 needs_external_surface_(false), |
| 195 is_fullscreen_(false), | 194 is_fullscreen_(false), |
| 196 video_frame_provider_client_(NULL), | 195 video_frame_provider_client_(NULL), |
|
jrummell
2015/11/12 00:23:06
Since you changed cdm_context_ to nullptr, should
xhwang
2015/11/12 06:28:37
Done.
| |
| 197 player_type_(MEDIA_PLAYER_TYPE_URL), | 196 player_type_(MEDIA_PLAYER_TYPE_URL), |
| 198 is_remote_(false), | 197 is_remote_(false), |
| 199 media_log_(params.media_log()), | 198 media_log_(params.media_log()), |
| 200 init_data_type_(media::EmeInitDataType::UNKNOWN), | 199 init_data_type_(media::EmeInitDataType::UNKNOWN), |
| 201 cdm_context_(NULL), | 200 cdm_context_(nullptr), |
| 202 allow_stored_credentials_(false), | 201 allow_stored_credentials_(false), |
| 203 is_local_resource_(false), | 202 is_local_resource_(false), |
| 204 interpolator_(&default_tick_clock_), | 203 interpolator_(&default_tick_clock_), |
| 205 weak_factory_(this) { | 204 weak_factory_(this) { |
| 206 DCHECK(player_manager_); | 205 DCHECK(player_manager_); |
| 207 DCHECK(cdm_factory_); | 206 DCHECK(cdm_factory_); |
| 208 | 207 |
| 209 DCHECK(main_thread_checker_.CalledOnValidThread()); | 208 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 210 stream_texture_factory_->AddObserver(this); | 209 stream_texture_factory_->AddObserver(this); |
| 211 | 210 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 | 318 |
| 320 media_source_delegate_.reset(new MediaSourceDelegate( | 319 media_source_delegate_.reset(new MediaSourceDelegate( |
| 321 demuxer, demuxer_client_id, media_task_runner_, media_log_)); | 320 demuxer, demuxer_client_id, media_task_runner_, media_log_)); |
| 322 | 321 |
| 323 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { | 322 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { |
| 324 media_source_delegate_->InitializeMediaSource( | 323 media_source_delegate_->InitializeMediaSource( |
| 325 base::Bind(&WebMediaPlayerAndroid::OnMediaSourceOpened, | 324 base::Bind(&WebMediaPlayerAndroid::OnMediaSourceOpened, |
| 326 weak_factory_.GetWeakPtr()), | 325 weak_factory_.GetWeakPtr()), |
| 327 base::Bind(&WebMediaPlayerAndroid::OnEncryptedMediaInitData, | 326 base::Bind(&WebMediaPlayerAndroid::OnEncryptedMediaInitData, |
| 328 weak_factory_.GetWeakPtr()), | 327 weak_factory_.GetWeakPtr()), |
| 329 base::Bind(&WebMediaPlayerAndroid::SetDecryptorReadyCB, | 328 base::Bind(&WebMediaPlayerAndroid::SetCdmReadyCB, |
| 330 weak_factory_.GetWeakPtr()), | 329 weak_factory_.GetWeakPtr()), |
| 331 base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, | 330 base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, |
| 332 weak_factory_.GetWeakPtr()), | 331 weak_factory_.GetWeakPtr()), |
| 333 base::Bind(&WebMediaPlayerAndroid::OnDurationChanged, | 332 base::Bind(&WebMediaPlayerAndroid::OnDurationChanged, |
| 334 weak_factory_.GetWeakPtr()), | 333 weak_factory_.GetWeakPtr()), |
| 335 base::Bind(&WebMediaPlayerAndroid::OnWaitingForDecryptionKey, | 334 base::Bind(&WebMediaPlayerAndroid::OnWaitingForDecryptionKey, |
| 336 weak_factory_.GetWeakPtr())); | 335 weak_factory_.GetWeakPtr())); |
| 337 InitializePlayer(url_, frame_->document().firstPartyForCookies(), | 336 InitializePlayer(url_, frame_->document().firstPartyForCookies(), |
| 338 true, demuxer_client_id); | 337 true, demuxer_client_id); |
| 339 } | 338 } |
| (...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1704 if (!cdm) { | 1703 if (!cdm) { |
| 1705 result.completeWithError( | 1704 result.completeWithError( |
| 1706 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, | 1705 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, |
| 1707 "The existing MediaKeys object cannot be removed at this time."); | 1706 "The existing MediaKeys object cannot be removed at this time."); |
| 1708 return; | 1707 return; |
| 1709 } | 1708 } |
| 1710 | 1709 |
| 1711 cdm_context_ = media::ToWebContentDecryptionModuleImpl(cdm)->GetCdmContext(); | 1710 cdm_context_ = media::ToWebContentDecryptionModuleImpl(cdm)->GetCdmContext(); |
| 1712 | 1711 |
| 1713 if (is_player_initialized_) { | 1712 if (is_player_initialized_) { |
| 1714 SetCdmInternal(media::BindToCurrentLoop( | 1713 SetCdmInternal( |
| 1715 base::Bind(&WebMediaPlayerAndroid::ContentDecryptionModuleAttached, | 1714 base::Bind(&WebMediaPlayerAndroid::ContentDecryptionModuleAttached, |
| 1716 weak_factory_.GetWeakPtr(), result))); | 1715 weak_factory_.GetWeakPtr(), result)); |
| 1717 } else { | 1716 } else { |
| 1718 // No pipeline/decoder connected, so resolve the promise. When something | 1717 // No pipeline/decoder connected, so resolve the promise. When something |
| 1719 // is connected, setting the CDM will happen in SetDecryptorReadyCB(). | 1718 // is connected, setting the CDM will happen in SetCdmReadyCB(). |
| 1720 ContentDecryptionModuleAttached(result, true); | 1719 ContentDecryptionModuleAttached(result, true); |
| 1721 } | 1720 } |
| 1722 } | 1721 } |
| 1723 | 1722 |
| 1724 void WebMediaPlayerAndroid::ContentDecryptionModuleAttached( | 1723 void WebMediaPlayerAndroid::ContentDecryptionModuleAttached( |
| 1725 blink::WebContentDecryptionModuleResult result, | 1724 blink::WebContentDecryptionModuleResult result, |
| 1726 bool success) { | 1725 bool success) { |
| 1727 if (success) { | 1726 if (success) { |
| 1728 result.complete(); | 1727 result.complete(); |
| 1729 return; | 1728 return; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1823 } | 1822 } |
| 1824 | 1823 |
| 1825 cdm_context_ = cdm_context; | 1824 cdm_context_ = cdm_context; |
| 1826 | 1825 |
| 1827 if (is_player_initialized_) | 1826 if (is_player_initialized_) |
| 1828 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); | 1827 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); |
| 1829 } | 1828 } |
| 1830 | 1829 |
| 1831 void WebMediaPlayerAndroid::SetCdmInternal( | 1830 void WebMediaPlayerAndroid::SetCdmInternal( |
| 1832 const media::CdmAttachedCB& cdm_attached_cb) { | 1831 const media::CdmAttachedCB& cdm_attached_cb) { |
| 1832 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1833 DCHECK(cdm_context_ && is_player_initialized_); | 1833 DCHECK(cdm_context_ && is_player_initialized_); |
| 1834 DCHECK(cdm_context_->GetDecryptor() || | 1834 DCHECK(cdm_context_->GetDecryptor() || |
| 1835 cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId) | 1835 cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId) |
| 1836 << "CDM should support either a Decryptor or a CDM ID."; | 1836 << "CDM should support either a Decryptor or a CDM ID."; |
| 1837 | 1837 |
| 1838 media::Decryptor* decryptor = cdm_context_->GetDecryptor(); | 1838 if (cdm_ready_cb_.is_null()) { |
| 1839 cdm_attached_cb.Run(true); | |
| 1840 return; | |
| 1841 } | |
| 1839 | 1842 |
| 1840 // Note: | 1843 // Satisfy |cdm_ready_cb_|. Use BindToCurrentLoop() since the callback could |
| 1841 // - If |decryptor| is non-null, only handles |decryptor_ready_cb_| and | 1844 // be fired on other threads. |
| 1842 // ignores the CDM ID. | 1845 base::ResetAndReturn(&cdm_ready_cb_) |
| 1843 // - If |decryptor| is null (in which case the CDM ID should be valid), | 1846 .Run(cdm_context_, media::BindToCurrentLoop(base::Bind( |
| 1844 // returns any pending |decryptor_ready_cb_| with null, so that | 1847 &WebMediaPlayerAndroid::OnCdmAttached, |
| 1845 // MediaSourceDelegate will fall back to use a browser side (IPC-based) CDM, | 1848 weak_factory_.GetWeakPtr(), cdm_attached_cb))); |
| 1846 // then calls SetCdm() through the |player_manager_|. | 1849 } |
| 1847 | 1850 |
| 1848 if (decryptor) { | 1851 void WebMediaPlayerAndroid::OnCdmAttached( |
| 1849 if (!decryptor_ready_cb_.is_null()) { | 1852 const media::CdmAttachedCB& cdm_attached_cb, |
| 1850 base::ResetAndReturn(&decryptor_ready_cb_) | 1853 bool success) { |
| 1851 .Run(decryptor, cdm_attached_cb); | 1854 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 1852 } else { | 1855 |
| 1853 cdm_attached_cb.Run(true); | 1856 if (!success) { |
| 1857 if (cdm_context_->GetCdmId() == media::CdmContext::kInvalidCdmId) { | |
| 1858 NOTREACHED() << "CDM cannot be attached to media player."; | |
| 1859 cdm_attached_cb.Run(false); | |
| 1860 return; | |
| 1861 } | |
| 1862 | |
| 1863 // If the CDM is not attached (e.g. the CDM does not support a Decryptor), | |
| 1864 // MediaSourceDelegate will fall back to use a browser side (IPC-based) CDM. | |
| 1865 player_manager_->SetCdm(player_id_, cdm_context_->GetCdmId()); | |
| 1866 } | |
| 1867 | |
| 1868 cdm_attached_cb.Run(true); | |
| 1869 } | |
| 1870 | |
| 1871 void WebMediaPlayerAndroid::SetCdmReadyCB( | |
| 1872 const media::CdmReadyCB& cdm_ready_cb) { | |
| 1873 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1874 DCHECK(is_player_initialized_); | |
| 1875 | |
| 1876 // Cancels the previous CDM request. | |
| 1877 if (cdm_ready_cb.is_null()) { | |
| 1878 if (!cdm_ready_cb_.is_null()) { | |
| 1879 base::ResetAndReturn(&cdm_ready_cb_) | |
| 1880 .Run(nullptr, base::Bind(&media::IgnoreCdmAttached)); | |
| 1854 } | 1881 } |
| 1855 return; | 1882 return; |
| 1856 } | 1883 } |
| 1857 | 1884 |
| 1858 // |decryptor| is null. | 1885 // TODO(xhwang): Support multiple CDM notification request (e.g. from |
| 1859 if (!decryptor_ready_cb_.is_null()) { | |
| 1860 base::ResetAndReturn(&decryptor_ready_cb_) | |
| 1861 .Run(nullptr, base::Bind(&media::IgnoreCdmAttached)); | |
| 1862 } | |
| 1863 | |
| 1864 DCHECK(cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId); | |
| 1865 player_manager_->SetCdm(player_id_, cdm_context_->GetCdmId()); | |
| 1866 cdm_attached_cb.Run(true); | |
| 1867 } | |
| 1868 | |
| 1869 void WebMediaPlayerAndroid::SetDecryptorReadyCB( | |
| 1870 const media::DecryptorReadyCB& decryptor_ready_cb) { | |
| 1871 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1872 DCHECK(is_player_initialized_); | |
| 1873 | |
| 1874 // Cancels the previous decryptor request. | |
| 1875 if (decryptor_ready_cb.is_null()) { | |
| 1876 if (!decryptor_ready_cb_.is_null()) { | |
| 1877 base::ResetAndReturn(&decryptor_ready_cb_) | |
| 1878 .Run(NULL, base::Bind(&media::IgnoreCdmAttached)); | |
| 1879 } | |
| 1880 return; | |
| 1881 } | |
| 1882 | |
| 1883 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | |
| 1884 // video and audio). The current implementation is okay for the current | 1886 // video and audio). The current implementation is okay for the current |
| 1885 // media pipeline since we initialize audio and video decoders in sequence. | 1887 // media pipeline since we initialize audio and video decoders in sequence. |
| 1886 // But WebMediaPlayerImpl should not depend on media pipeline's implementation | 1888 // But WebMediaPlayerAndroid should not depend on media pipeline's |
| 1887 // detail. | 1889 // implementation detail. |
| 1888 DCHECK(decryptor_ready_cb_.is_null()); | 1890 DCHECK(cdm_ready_cb_.is_null()); |
| 1891 cdm_ready_cb_ = cdm_ready_cb; | |
| 1889 | 1892 |
| 1890 if (cdm_context_) { | 1893 if (cdm_context_) |
| 1891 decryptor_ready_cb.Run(cdm_context_->GetDecryptor(), | 1894 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); |
| 1892 base::Bind(&media::IgnoreCdmAttached)); | |
| 1893 return; | |
| 1894 } | |
| 1895 | |
| 1896 decryptor_ready_cb_ = decryptor_ready_cb; | |
| 1897 } | 1895 } |
| 1898 | 1896 |
| 1899 bool WebMediaPlayerAndroid::supportsOverlayFullscreenVideo() { | 1897 bool WebMediaPlayerAndroid::supportsOverlayFullscreenVideo() { |
| 1900 return true; | 1898 return true; |
| 1901 } | 1899 } |
| 1902 | 1900 |
| 1903 void WebMediaPlayerAndroid::enterFullscreen() { | 1901 void WebMediaPlayerAndroid::enterFullscreen() { |
| 1904 if (is_player_initialized_) | 1902 if (is_player_initialized_) |
| 1905 player_manager_->EnterFullscreen(player_id_); | 1903 player_manager_->EnterFullscreen(player_id_); |
| 1906 SetNeedsEstablishPeer(false); | 1904 SetNeedsEstablishPeer(false); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1921 | 1919 |
| 1922 bool is_hls = IsHLSStream(); | 1920 bool is_hls = IsHLSStream(); |
| 1923 UMA_HISTOGRAM_BOOLEAN("Media.Android.IsHttpLiveStreamingMedia", is_hls); | 1921 UMA_HISTOGRAM_BOOLEAN("Media.Android.IsHttpLiveStreamingMedia", is_hls); |
| 1924 if (is_hls) { | 1922 if (is_hls) { |
| 1925 media::RecordOriginOfHLSPlayback( | 1923 media::RecordOriginOfHLSPlayback( |
| 1926 GURL(frame_->document().securityOrigin().toString())); | 1924 GURL(frame_->document().securityOrigin().toString())); |
| 1927 } | 1925 } |
| 1928 } | 1926 } |
| 1929 | 1927 |
| 1930 } // namespace content | 1928 } // namespace content |
| OLD | NEW |