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 "webkit/renderer/media/webmediaplayer_impl.h" | 5 #include "webkit/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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 starting_(false), | 147 starting_(false), |
148 chunk_demuxer_(NULL), | 148 chunk_demuxer_(NULL), |
149 pending_repaint_(false), | 149 pending_repaint_(false), |
150 pending_size_change_(false), | 150 pending_size_change_(false), |
151 video_frame_provider_client_(NULL), | 151 video_frame_provider_client_(NULL), |
152 text_track_index_(0) { | 152 text_track_index_(0) { |
153 media_log_->AddEvent( | 153 media_log_->AddEvent( |
154 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 154 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
155 | 155 |
156 CHECK(media_thread_.Start()); | 156 CHECK(media_thread_.Start()); |
157 pipeline_.reset(new media::Pipeline( | 157 pipeline_.reset(new media::Pipeline(media_thread_.message_loop_proxy(), |
158 media_thread_.message_loop_proxy(), media_log_)); | 158 media_log_.get())); |
159 | 159 |
160 // Let V8 know we started new thread if we did not do it yet. | 160 // Let V8 know we started new thread if we did not do it yet. |
161 // Made separate task to avoid deletion of player currently being created. | 161 // Made separate task to avoid deletion of player currently being created. |
162 // Also, delaying GC until after player starts gets rid of starting lag -- | 162 // Also, delaying GC until after player starts gets rid of starting lag -- |
163 // collection happens in parallel with playing. | 163 // collection happens in parallel with playing. |
164 // | 164 // |
165 // TODO(enal): remove when we get rid of per-audio-stream thread. | 165 // TODO(enal): remove when we get rid of per-audio-stream thread. |
166 main_loop_->PostTask( | 166 main_loop_->PostTask( |
167 FROM_HERE, | 167 FROM_HERE, |
168 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | 168 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, |
169 AsWeakPtr())); | 169 AsWeakPtr())); |
170 | 170 |
171 // Also we want to be notified of |main_loop_| destruction. | 171 // Also we want to be notified of |main_loop_| destruction. |
172 base::MessageLoop::current()->AddDestructionObserver(this); | 172 base::MessageLoop::current()->AddDestructionObserver(this); |
173 | 173 |
174 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { | 174 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { |
175 decryptor_.reset(new ProxyDecryptor( | 175 decryptor_.reset(new ProxyDecryptor( |
176 client, | 176 client, |
177 frame, | 177 frame, |
178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), | 178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), |
179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), | 179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), |
180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), | 180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), |
181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); | 181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); |
182 } | 182 } |
183 | 183 |
184 // Use the null sink if no sink was provided. | 184 // Use the null sink if no sink was provided. |
185 audio_source_provider_ = new WebAudioSourceProviderImpl( | 185 audio_source_provider_ = new WebAudioSourceProviderImpl( |
186 params.audio_renderer_sink() ? params.audio_renderer_sink() : | 186 params.audio_renderer_sink().get() |
187 new media::NullAudioSink(media_thread_.message_loop_proxy())); | 187 ? params.audio_renderer_sink() |
| 188 : new media::NullAudioSink(media_thread_.message_loop_proxy())); |
188 } | 189 } |
189 | 190 |
190 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 191 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
191 SetVideoFrameProviderClient(NULL); | 192 SetVideoFrameProviderClient(NULL); |
192 GetClient()->setWebLayer(NULL); | 193 GetClient()->setWebLayer(NULL); |
193 | 194 |
194 DCHECK(main_loop_->BelongsToCurrentThread()); | 195 DCHECK(main_loop_->BelongsToCurrentThread()); |
195 media_log_->AddEvent( | 196 media_log_->AddEvent( |
196 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 197 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
197 | 198 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } // anonymous namespace | 242 } // anonymous namespace |
242 | 243 |
243 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { | 244 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { |
244 DCHECK(main_loop_->BelongsToCurrentThread()); | 245 DCHECK(main_loop_->BelongsToCurrentThread()); |
245 | 246 |
246 LoadSetup(url); | 247 LoadSetup(url); |
247 | 248 |
248 // Otherwise it's a regular request which requires resolving the URL first. | 249 // Otherwise it's a regular request which requires resolving the URL first. |
249 GURL gurl(url); | 250 GURL gurl(url); |
250 data_source_.reset(new BufferedDataSource( | 251 data_source_.reset(new BufferedDataSource( |
251 main_loop_, frame_, media_log_, base::Bind( | 252 main_loop_, |
252 &WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 253 frame_, |
| 254 media_log_.get(), |
| 255 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
253 data_source_->Initialize( | 256 data_source_->Initialize( |
254 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 257 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
255 base::Bind( | 258 base::Bind( |
256 &WebMediaPlayerImpl::DataSourceInitialized, | 259 &WebMediaPlayerImpl::DataSourceInitialized, |
257 AsWeakPtr(), gurl)); | 260 AsWeakPtr(), gurl)); |
258 | 261 |
259 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 262 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |
260 } | 263 } |
261 | 264 |
262 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, | 265 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 } | 538 } |
536 | 539 |
537 // Avoid locking and potentially blocking the video rendering thread while | 540 // Avoid locking and potentially blocking the video rendering thread while |
538 // painting in software. | 541 // painting in software. |
539 scoped_refptr<media::VideoFrame> video_frame; | 542 scoped_refptr<media::VideoFrame> video_frame; |
540 { | 543 { |
541 base::AutoLock auto_lock(lock_); | 544 base::AutoLock auto_lock(lock_); |
542 video_frame = current_frame_; | 545 video_frame = current_frame_; |
543 } | 546 } |
544 gfx::Rect gfx_rect(rect); | 547 gfx::Rect gfx_rect(rect); |
545 skcanvas_video_renderer_.Paint(video_frame, canvas, gfx_rect, alpha); | 548 skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha); |
546 } | 549 } |
547 | 550 |
548 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { | 551 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { |
549 if (data_source_) | 552 if (data_source_) |
550 return data_source_->HasSingleOrigin(); | 553 return data_source_->HasSingleOrigin(); |
551 return true; | 554 return true; |
552 } | 555 } |
553 | 556 |
554 bool WebMediaPlayerImpl::didPassCORSAccessCheck() const { | 557 bool WebMediaPlayerImpl::didPassCORSAccessCheck() const { |
555 if (data_source_) | 558 if (data_source_) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 unsigned int level, | 630 unsigned int level, |
628 unsigned int internal_format, | 631 unsigned int internal_format, |
629 unsigned int type, | 632 unsigned int type, |
630 bool premultiply_alpha, | 633 bool premultiply_alpha, |
631 bool flip_y) { | 634 bool flip_y) { |
632 scoped_refptr<media::VideoFrame> video_frame; | 635 scoped_refptr<media::VideoFrame> video_frame; |
633 { | 636 { |
634 base::AutoLock auto_lock(lock_); | 637 base::AutoLock auto_lock(lock_); |
635 video_frame = current_frame_; | 638 video_frame = current_frame_; |
636 } | 639 } |
637 if (video_frame && | 640 if (video_frame.get() && |
638 video_frame->format() == media::VideoFrame::NATIVE_TEXTURE && | 641 video_frame->format() == media::VideoFrame::NATIVE_TEXTURE && |
639 video_frame->texture_target() == GL_TEXTURE_2D) { | 642 video_frame->texture_target() == GL_TEXTURE_2D) { |
640 uint32 source_texture = video_frame->texture_id(); | 643 uint32 source_texture = video_frame->texture_id(); |
641 // The video is stored in a unmultiplied format, so premultiply | 644 // The video is stored in a unmultiplied format, so premultiply |
642 // if necessary. | 645 // if necessary. |
643 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, | 646 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, |
644 premultiply_alpha); | 647 premultiply_alpha); |
645 // Application itself needs to take care of setting the right flip_y | 648 // Application itself needs to take care of setting the right flip_y |
646 // value down to get the expected result. | 649 // value down to get the expected result. |
647 // flip_y==true means to reverse the video orientation while | 650 // flip_y==true means to reverse the video orientation while |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 ScopedVector<media::AudioDecoder> audio_decoders; | 1093 ScopedVector<media::AudioDecoder> audio_decoders; |
1091 audio_decoders.push_back(new media::FFmpegAudioDecoder( | 1094 audio_decoders.push_back(new media::FFmpegAudioDecoder( |
1092 media_thread_.message_loop_proxy())); | 1095 media_thread_.message_loop_proxy())); |
1093 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { | 1096 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { |
1094 audio_decoders.push_back(new media::OpusAudioDecoder( | 1097 audio_decoders.push_back(new media::OpusAudioDecoder( |
1095 media_thread_.message_loop_proxy())); | 1098 media_thread_.message_loop_proxy())); |
1096 } | 1099 } |
1097 | 1100 |
1098 scoped_ptr<media::AudioRenderer> audio_renderer( | 1101 scoped_ptr<media::AudioRenderer> audio_renderer( |
1099 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), | 1102 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), |
1100 audio_source_provider_, | 1103 audio_source_provider_.get(), |
1101 audio_decoders.Pass(), | 1104 audio_decoders.Pass(), |
1102 set_decryptor_ready_cb)); | 1105 set_decryptor_ready_cb)); |
1103 filter_collection->SetAudioRenderer(audio_renderer.Pass()); | 1106 filter_collection->SetAudioRenderer(audio_renderer.Pass()); |
1104 | 1107 |
1105 // Create our video decoders and renderer. | 1108 // Create our video decoders and renderer. |
1106 ScopedVector<media::VideoDecoder> video_decoders; | 1109 ScopedVector<media::VideoDecoder> video_decoders; |
1107 | 1110 |
1108 if (gpu_factories_) { | 1111 if (gpu_factories_.get()) { |
1109 video_decoders.push_back(new media::GpuVideoDecoder( | 1112 video_decoders.push_back(new media::GpuVideoDecoder( |
1110 media_thread_.message_loop_proxy(), gpu_factories_)); | 1113 media_thread_.message_loop_proxy(), gpu_factories_)); |
1111 } | 1114 } |
1112 | 1115 |
1113 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released | 1116 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released |
1114 // (http://crbug.com/174287) . | 1117 // (http://crbug.com/174287) . |
1115 #if !defined(MEDIA_DISABLE_LIBVPX) | 1118 #if !defined(MEDIA_DISABLE_LIBVPX) |
1116 if (cmd_line->HasSwitch(switches::kEnableVp9Playback) || | 1119 if (cmd_line->HasSwitch(switches::kEnableVp9Playback) || |
1117 cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) { | 1120 cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) { |
1118 video_decoders.push_back(new media::VpxVideoDecoder( | 1121 video_decoders.push_back(new media::VpxVideoDecoder( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 DCHECK(main_loop_->BelongsToCurrentThread()); | 1173 DCHECK(main_loop_->BelongsToCurrentThread()); |
1171 | 1174 |
1172 // Abort any pending IO so stopping the pipeline doesn't get blocked. | 1175 // Abort any pending IO so stopping the pipeline doesn't get blocked. |
1173 if (data_source_) | 1176 if (data_source_) |
1174 data_source_->Abort(); | 1177 data_source_->Abort(); |
1175 if (chunk_demuxer_) { | 1178 if (chunk_demuxer_) { |
1176 chunk_demuxer_->Shutdown(); | 1179 chunk_demuxer_->Shutdown(); |
1177 chunk_demuxer_ = NULL; | 1180 chunk_demuxer_ = NULL; |
1178 } | 1181 } |
1179 | 1182 |
1180 if (gpu_factories_) { | 1183 if (gpu_factories_.get()) { |
1181 gpu_factories_->Abort(); | 1184 gpu_factories_->Abort(); |
1182 gpu_factories_ = NULL; | 1185 gpu_factories_ = NULL; |
1183 } | 1186 } |
1184 | 1187 |
1185 // Make sure to kill the pipeline so there's no more media threads running. | 1188 // Make sure to kill the pipeline so there's no more media threads running. |
1186 // Note: stopping the pipeline might block for a long time. | 1189 // Note: stopping the pipeline might block for a long time. |
1187 base::WaitableEvent waiter(false, false); | 1190 base::WaitableEvent waiter(false, false); |
1188 pipeline_->Stop(base::Bind( | 1191 pipeline_->Stop(base::Bind( |
1189 &base::WaitableEvent::Signal, base::Unretained(&waiter))); | 1192 &base::WaitableEvent::Signal, base::Unretained(&waiter))); |
1190 waiter.Wait(); | 1193 waiter.Wait(); |
(...skipping 12 matching lines...) Expand all Loading... |
1203 data_source_.reset(); | 1206 data_source_.reset(); |
1204 } | 1207 } |
1205 | 1208 |
1206 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 1209 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |
1207 DCHECK(main_loop_->BelongsToCurrentThread()); | 1210 DCHECK(main_loop_->BelongsToCurrentThread()); |
1208 DCHECK(client_); | 1211 DCHECK(client_); |
1209 return client_; | 1212 return client_; |
1210 } | 1213 } |
1211 | 1214 |
1212 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 1215 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |
1213 return audio_source_provider_; | 1216 return audio_source_provider_.get(); |
1214 } | 1217 } |
1215 | 1218 |
1216 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 1219 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
1217 DCHECK(main_loop_->BelongsToCurrentThread()); | 1220 DCHECK(main_loop_->BelongsToCurrentThread()); |
1218 incremented_externally_allocated_memory_ = true; | 1221 incremented_externally_allocated_memory_ = true; |
1219 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 1222 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |
1220 } | 1223 } |
1221 | 1224 |
1222 double WebMediaPlayerImpl::GetPipelineDuration() const { | 1225 double WebMediaPlayerImpl::GetPipelineDuration() const { |
1223 base::TimeDelta duration = pipeline_->GetMediaDuration(); | 1226 base::TimeDelta duration = pipeline_->GetMediaDuration(); |
(...skipping 10 matching lines...) Expand all Loading... |
1234 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 1237 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
1235 return; | 1238 return; |
1236 | 1239 |
1237 GetClient()->durationChanged(); | 1240 GetClient()->durationChanged(); |
1238 } | 1241 } |
1239 | 1242 |
1240 void WebMediaPlayerImpl::FrameReady( | 1243 void WebMediaPlayerImpl::FrameReady( |
1241 const scoped_refptr<media::VideoFrame>& frame) { | 1244 const scoped_refptr<media::VideoFrame>& frame) { |
1242 base::AutoLock auto_lock(lock_); | 1245 base::AutoLock auto_lock(lock_); |
1243 | 1246 |
1244 if (current_frame_ && | 1247 if (current_frame_.get() && |
1245 current_frame_->natural_size() != frame->natural_size() && | 1248 current_frame_->natural_size() != frame->natural_size() && |
1246 !pending_size_change_) { | 1249 !pending_size_change_) { |
1247 pending_size_change_ = true; | 1250 pending_size_change_ = true; |
1248 } | 1251 } |
1249 | 1252 |
1250 current_frame_ = frame; | 1253 current_frame_ = frame; |
1251 | 1254 |
1252 if (pending_repaint_) | 1255 if (pending_repaint_) |
1253 return; | 1256 return; |
1254 | 1257 |
1255 pending_repaint_ = true; | 1258 pending_repaint_ = true; |
1256 main_loop_->PostTask(FROM_HERE, base::Bind( | 1259 main_loop_->PostTask(FROM_HERE, base::Bind( |
1257 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); | 1260 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); |
1258 } | 1261 } |
1259 | 1262 |
1260 } // namespace webkit_media | 1263 } // namespace webkit_media |
OLD | NEW |