| 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 |