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/webmediaplayer_impl.h" | 5 #include "content/renderer/media/webmediaplayer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 #include "media/filters/video_renderer_impl.h" | 58 #include "media/filters/video_renderer_impl.h" |
59 #include "media/filters/vpx_video_decoder.h" | 59 #include "media/filters/vpx_video_decoder.h" |
60 #include "third_party/WebKit/public/platform/WebMediaSource.h" | 60 #include "third_party/WebKit/public/platform/WebMediaSource.h" |
61 #include "third_party/WebKit/public/platform/WebRect.h" | 61 #include "third_party/WebKit/public/platform/WebRect.h" |
62 #include "third_party/WebKit/public/platform/WebSize.h" | 62 #include "third_party/WebKit/public/platform/WebSize.h" |
63 #include "third_party/WebKit/public/platform/WebString.h" | 63 #include "third_party/WebKit/public/platform/WebString.h" |
64 #include "third_party/WebKit/public/platform/WebURL.h" | 64 #include "third_party/WebKit/public/platform/WebURL.h" |
65 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 65 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
66 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 66 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
67 #include "third_party/WebKit/public/web/WebView.h" | 67 #include "third_party/WebKit/public/web/WebView.h" |
68 #include "v8/include/v8.h" | |
69 | 68 |
70 using blink::WebCanvas; | 69 using blink::WebCanvas; |
71 using blink::WebMediaPlayer; | 70 using blink::WebMediaPlayer; |
72 using blink::WebRect; | 71 using blink::WebRect; |
73 using blink::WebSize; | 72 using blink::WebSize; |
74 using blink::WebString; | 73 using blink::WebString; |
75 using media::PipelineStatus; | 74 using media::PipelineStatus; |
76 | 75 |
77 namespace { | 76 namespace { |
78 | 77 |
79 // Amount of extra memory used by each player instance reported to V8. | |
80 // It is not exact number -- first, it differs on different platforms, | |
81 // and second, it is very hard to calculate. Instead, use some arbitrary | |
82 // value that will cause garbage collection from time to time. We don't want | |
83 // it to happen on every allocation, but don't want 5k players to sit in memory | |
84 // either. Looks that chosen constant achieves both goals, at least for audio | |
85 // objects. (Do not worry about video objects yet, JS programs do not create | |
86 // thousands of them...) | |
87 const int kPlayerExtraMemory = 1024 * 1024; | |
88 | |
89 // Limits the range of playback rate. | 78 // Limits the range of playback rate. |
90 // | 79 // |
91 // TODO(kylep): Revisit these. | 80 // TODO(kylep): Revisit these. |
92 // | 81 // |
93 // Vista has substantially lower performance than XP or Windows7. If you speed | 82 // Vista has substantially lower performance than XP or Windows7. If you speed |
94 // up a video too much, it can't keep up, and rendering stops updating except on | 83 // up a video too much, it can't keep up, and rendering stops updating except on |
95 // the time bar. For really high speeds, audio becomes a bottleneck and we just | 84 // the time bar. For really high speeds, audio becomes a bottleneck and we just |
96 // use up the data we have, which may not achieve the speed requested, but will | 85 // use up the data we have, which may not achieve the speed requested, but will |
97 // not crash the tab. | 86 // not crash the tab. |
98 // | 87 // |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 opaque_(false), | 157 opaque_(false), |
169 paused_(true), | 158 paused_(true), |
170 seeking_(false), | 159 seeking_(false), |
171 playback_rate_(0.0f), | 160 playback_rate_(0.0f), |
172 pending_seek_(false), | 161 pending_seek_(false), |
173 pending_seek_seconds_(0.0f), | 162 pending_seek_seconds_(0.0f), |
174 should_notify_time_changed_(false), | 163 should_notify_time_changed_(false), |
175 client_(client), | 164 client_(client), |
176 delegate_(delegate), | 165 delegate_(delegate), |
177 defer_load_cb_(params.defer_load_cb()), | 166 defer_load_cb_(params.defer_load_cb()), |
178 incremented_externally_allocated_memory_(false), | |
179 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), | 167 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), |
180 supports_save_(true), | 168 supports_save_(true), |
181 chunk_demuxer_(NULL), | 169 chunk_demuxer_(NULL), |
182 // Threaded compositing isn't enabled universally yet. | 170 // Threaded compositing isn't enabled universally yet. |
183 compositor_task_runner_( | 171 compositor_task_runner_( |
184 RenderThreadImpl::current()->compositor_message_loop_proxy() | 172 RenderThreadImpl::current()->compositor_message_loop_proxy() |
185 ? RenderThreadImpl::current()->compositor_message_loop_proxy() | 173 ? RenderThreadImpl::current()->compositor_message_loop_proxy() |
186 : base::MessageLoopProxy::current()), | 174 : base::MessageLoopProxy::current()), |
187 compositor_(new VideoFrameCompositor( | 175 compositor_(new VideoFrameCompositor( |
188 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), | 176 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), |
189 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), | 177 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), |
190 text_track_index_(0), | 178 text_track_index_(0), |
191 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { | 179 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { |
192 DCHECK(encrypted_media_support_); | 180 DCHECK(encrypted_media_support_); |
193 | 181 |
194 media_log_->AddEvent( | 182 media_log_->AddEvent( |
195 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 183 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
196 | 184 |
197 // |gpu_factories_| requires that its entry points be called on its | 185 // |gpu_factories_| requires that its entry points be called on its |
198 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the | 186 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the |
199 // factories, require that their message loops are identical. | 187 // factories, require that their message loops are identical. |
200 DCHECK(!gpu_factories_.get() || | 188 DCHECK(!gpu_factories_.get() || |
201 (gpu_factories_->GetTaskRunner() == media_loop_.get())); | 189 (gpu_factories_->GetTaskRunner() == media_loop_.get())); |
202 | 190 |
203 // Let V8 know we started new thread if we did not do it yet. | |
204 // Made separate task to avoid deletion of player currently being created. | |
205 // Also, delaying GC until after player starts gets rid of starting lag -- | |
206 // collection happens in parallel with playing. | |
207 // | |
208 // TODO(enal): remove when we get rid of per-audio-stream thread. | |
209 main_loop_->PostTask( | |
210 FROM_HERE, | |
211 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | |
212 AsWeakPtr())); | |
213 | |
214 // Use the null sink if no sink was provided. | 191 // Use the null sink if no sink was provided. |
215 audio_source_provider_ = new WebAudioSourceProviderImpl( | 192 audio_source_provider_ = new WebAudioSourceProviderImpl( |
216 params.audio_renderer_sink().get() | 193 params.audio_renderer_sink().get() |
217 ? params.audio_renderer_sink() | 194 ? params.audio_renderer_sink() |
218 : new media::NullAudioSink(media_loop_)); | 195 : new media::NullAudioSink(media_loop_)); |
219 } | 196 } |
220 | 197 |
221 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 198 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
222 client_->setWebLayer(NULL); | 199 client_->setWebLayer(NULL); |
223 | 200 |
(...skipping 15 matching lines...) Expand all Loading... |
239 gpu_factories_ = NULL; | 216 gpu_factories_ = NULL; |
240 | 217 |
241 // Make sure to kill the pipeline so there's no more media threads running. | 218 // Make sure to kill the pipeline so there's no more media threads running. |
242 // Note: stopping the pipeline might block for a long time. | 219 // Note: stopping the pipeline might block for a long time. |
243 base::WaitableEvent waiter(false, false); | 220 base::WaitableEvent waiter(false, false); |
244 pipeline_.Stop( | 221 pipeline_.Stop( |
245 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); | 222 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); |
246 waiter.Wait(); | 223 waiter.Wait(); |
247 | 224 |
248 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); | 225 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); |
249 | |
250 // Let V8 know we are not using extra resources anymore. | |
251 if (incremented_externally_allocated_memory_) { | |
252 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | |
253 -kPlayerExtraMemory); | |
254 incremented_externally_allocated_memory_ = false; | |
255 } | |
256 } | 226 } |
257 | 227 |
258 void WebMediaPlayerImpl::load(LoadType load_type, const blink::WebURL& url, | 228 void WebMediaPlayerImpl::load(LoadType load_type, const blink::WebURL& url, |
259 CORSMode cors_mode) { | 229 CORSMode cors_mode) { |
260 DVLOG(1) << __FUNCTION__ << "(" << load_type << ", " << url << ", " | 230 DVLOG(1) << __FUNCTION__ << "(" << load_type << ", " << url << ", " |
261 << cors_mode << ")"; | 231 << cors_mode << ")"; |
262 if (!defer_load_cb_.is_null()) { | 232 if (!defer_load_cb_.is_null()) { |
263 defer_load_cb_.Run(base::Bind( | 233 defer_load_cb_.Run(base::Bind( |
264 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); | 234 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); |
265 return; | 235 return; |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 | 951 |
982 ready_state_ = state; | 952 ready_state_ = state; |
983 // Always notify to ensure client has the latest value. | 953 // Always notify to ensure client has the latest value. |
984 client_->readyStateChanged(); | 954 client_->readyStateChanged(); |
985 } | 955 } |
986 | 956 |
987 blink::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 957 blink::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |
988 return audio_source_provider_.get(); | 958 return audio_source_provider_.get(); |
989 } | 959 } |
990 | 960 |
991 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | |
992 DCHECK(main_loop_->BelongsToCurrentThread()); | |
993 incremented_externally_allocated_memory_ = true; | |
994 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | |
995 kPlayerExtraMemory); | |
996 } | |
997 | |
998 double WebMediaPlayerImpl::GetPipelineDuration() const { | 961 double WebMediaPlayerImpl::GetPipelineDuration() const { |
999 base::TimeDelta duration = pipeline_.GetMediaDuration(); | 962 base::TimeDelta duration = pipeline_.GetMediaDuration(); |
1000 | 963 |
1001 // Return positive infinity if the resource is unbounded. | 964 // Return positive infinity if the resource is unbounded. |
1002 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration | 965 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration |
1003 if (duration == media::kInfiniteDuration()) | 966 if (duration == media::kInfiniteDuration()) |
1004 return std::numeric_limits<double>::infinity(); | 967 return std::numeric_limits<double>::infinity(); |
1005 | 968 |
1006 return duration.InSecondsF(); | 969 return duration.InSecondsF(); |
1007 } | 970 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 compositor_task_runner_->PostTask(FROM_HERE, | 1028 compositor_task_runner_->PostTask(FROM_HERE, |
1066 base::Bind(&GetCurrentFrameAndSignal, | 1029 base::Bind(&GetCurrentFrameAndSignal, |
1067 base::Unretained(compositor_), | 1030 base::Unretained(compositor_), |
1068 &video_frame, | 1031 &video_frame, |
1069 &event)); | 1032 &event)); |
1070 event.Wait(); | 1033 event.Wait(); |
1071 return video_frame; | 1034 return video_frame; |
1072 } | 1035 } |
1073 | 1036 |
1074 } // namespace content | 1037 } // namespace content |
OLD | NEW |