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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/command_line.h" | |
15 #include "base/debug/crash_logging.h" | 14 #include "base/debug/crash_logging.h" |
16 #include "base/message_loop_proxy.h" | 15 #include "base/message_loop_proxy.h" |
17 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
18 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
19 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
20 #include "cc/layers/video_layer.h" | 19 #include "cc/layers/video_layer.h" |
21 #include "gpu/GLES2/gl2extchromium.h" | 20 #include "gpu/GLES2/gl2extchromium.h" |
22 #include "media/audio/null_audio_sink.h" | 21 #include "media/audio/null_audio_sink.h" |
23 #include "media/base/bind_to_loop.h" | 22 #include "media/base/bind_to_loop.h" |
24 #include "media/base/filter_collection.h" | 23 #include "media/base/filter_collection.h" |
25 #include "media/base/limits.h" | 24 #include "media/base/limits.h" |
26 #include "media/base/media_log.h" | 25 #include "media/base/media_log.h" |
27 #include "media/base/media_switches.h" | |
28 #include "media/base/pipeline.h" | 26 #include "media/base/pipeline.h" |
29 #include "media/base/video_frame.h" | 27 #include "media/base/video_frame.h" |
30 #include "media/filters/audio_renderer_impl.h" | 28 #include "media/filters/audio_renderer_impl.h" |
31 #include "media/filters/chunk_demuxer.h" | 29 #include "media/filters/chunk_demuxer.h" |
32 #include "media/filters/ffmpeg_audio_decoder.h" | |
33 #include "media/filters/ffmpeg_demuxer.h" | |
34 #include "media/filters/ffmpeg_video_decoder.h" | |
35 #include "media/filters/opus_audio_decoder.h" | |
36 #include "media/filters/video_renderer_base.h" | 30 #include "media/filters/video_renderer_base.h" |
37 #include "media/filters/vpx_video_decoder.h" | |
38 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" | 31 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" |
39 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" | 32 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" |
40 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | 33 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" |
41 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | 34 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" |
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h" |
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" |
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
45 #include "v8/include/v8.h" | 38 #include "v8/include/v8.h" |
46 #include "webkit/compositor_bindings/web_layer_impl.h" | 39 #include "webkit/compositor_bindings/web_layer_impl.h" |
47 #include "webkit/media/buffered_data_source.h" | 40 #include "webkit/media/buffered_data_source.h" |
| 41 #include "webkit/media/filter_helpers.h" |
48 #include "webkit/media/webaudiosourceprovider_impl.h" | 42 #include "webkit/media/webaudiosourceprovider_impl.h" |
49 #include "webkit/media/webmediaplayer_delegate.h" | 43 #include "webkit/media/webmediaplayer_delegate.h" |
50 #include "webkit/media/webmediaplayer_params.h" | 44 #include "webkit/media/webmediaplayer_params.h" |
51 #include "webkit/media/webmediaplayer_util.h" | 45 #include "webkit/media/webmediaplayer_util.h" |
52 #include "webkit/media/webmediasourceclient_impl.h" | 46 #include "webkit/media/webmediasourceclient_impl.h" |
53 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" | 47 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" |
54 | 48 |
55 using WebKit::WebCanvas; | 49 using WebKit::WebCanvas; |
56 using WebKit::WebMediaPlayer; | 50 using WebKit::WebMediaPlayer; |
57 using WebKit::WebRect; | 51 using WebKit::WebRect; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 125 |
132 WebMediaPlayerImpl::WebMediaPlayerImpl( | 126 WebMediaPlayerImpl::WebMediaPlayerImpl( |
133 WebKit::WebFrame* frame, | 127 WebKit::WebFrame* frame, |
134 WebKit::WebMediaPlayerClient* client, | 128 WebKit::WebMediaPlayerClient* client, |
135 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 129 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
136 const WebMediaPlayerParams& params) | 130 const WebMediaPlayerParams& params) |
137 : frame_(frame), | 131 : frame_(frame), |
138 network_state_(WebMediaPlayer::NetworkStateEmpty), | 132 network_state_(WebMediaPlayer::NetworkStateEmpty), |
139 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 133 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
140 main_loop_(base::MessageLoopProxy::current()), | 134 main_loop_(base::MessageLoopProxy::current()), |
| 135 filter_collection_(new media::FilterCollection()), |
141 media_thread_("MediaPipeline"), | 136 media_thread_("MediaPipeline"), |
142 paused_(true), | 137 paused_(true), |
143 seeking_(false), | 138 seeking_(false), |
144 playback_rate_(0.0f), | 139 playback_rate_(0.0f), |
145 pending_seek_(false), | 140 pending_seek_(false), |
146 pending_seek_seconds_(0.0f), | 141 pending_seek_seconds_(0.0f), |
147 client_(client), | 142 client_(client), |
148 delegate_(delegate), | 143 delegate_(delegate), |
149 media_log_(params.media_log()), | 144 media_log_(params.media_log()), |
150 accelerated_compositing_reported_(false), | 145 accelerated_compositing_reported_(false), |
151 incremented_externally_allocated_memory_(false), | 146 incremented_externally_allocated_memory_(false), |
152 gpu_factories_(params.gpu_factories()), | |
153 is_local_source_(false), | 147 is_local_source_(false), |
154 supports_save_(true), | 148 supports_save_(true), |
155 starting_(false), | 149 starting_(false), |
156 pending_repaint_(false), | 150 pending_repaint_(false), |
157 video_frame_provider_client_(NULL) { | 151 video_frame_provider_client_(NULL) { |
158 media_log_->AddEvent( | 152 media_log_->AddEvent( |
159 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 153 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
160 | 154 |
161 CHECK(media_thread_.Start()); | 155 CHECK(media_thread_.Start()); |
162 pipeline_ = new media::Pipeline( | 156 pipeline_ = new media::Pipeline( |
163 media_thread_.message_loop_proxy(), media_log_); | 157 media_thread_.message_loop_proxy(), media_log_); |
164 | 158 |
165 // Let V8 know we started new thread if we did not do it yet. | 159 // Let V8 know we started new thread if we did not do it yet. |
166 // Made separate task to avoid deletion of player currently being created. | 160 // Made separate task to avoid deletion of player currently being created. |
167 // Also, delaying GC until after player starts gets rid of starting lag -- | 161 // Also, delaying GC until after player starts gets rid of starting lag -- |
168 // collection happens in parallel with playing. | 162 // collection happens in parallel with playing. |
169 // | 163 // |
170 // TODO(enal): remove when we get rid of per-audio-stream thread. | 164 // TODO(enal): remove when we get rid of per-audio-stream thread. |
171 main_loop_->PostTask( | 165 main_loop_->PostTask( |
172 FROM_HERE, | 166 FROM_HERE, |
173 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | 167 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, |
174 AsWeakPtr())); | 168 AsWeakPtr())); |
175 | 169 |
176 // Also we want to be notified of |main_loop_| destruction. | 170 // Also we want to be notified of |main_loop_| destruction. |
177 MessageLoop::current()->AddDestructionObserver(this); | 171 MessageLoop::current()->AddDestructionObserver(this); |
178 | 172 |
| 173 media::SetDecryptorReadyCB set_decryptor_ready_cb; |
179 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { | 174 if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { |
180 decryptor_.reset(new ProxyDecryptor( | 175 decryptor_.reset(new ProxyDecryptor( |
181 client, | 176 client, |
182 frame, | 177 frame, |
183 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), | 178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), |
184 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), | 179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), |
185 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), | 180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), |
186 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); | 181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); |
| 182 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB, |
| 183 base::Unretained(decryptor_.get())); |
187 } | 184 } |
188 | 185 |
189 // Use the null sink if no sink was provided. | 186 // Create the GPU video decoder if factories were provided. |
| 187 if (params.gpu_factories()) { |
| 188 filter_collection_->GetVideoDecoders()->push_back( |
| 189 new media::GpuVideoDecoder( |
| 190 media_thread_.message_loop_proxy(), |
| 191 params.gpu_factories())); |
| 192 gpu_factories_ = params.gpu_factories(); |
| 193 } |
| 194 |
| 195 // Create default video renderer. |
| 196 scoped_ptr<media::VideoRenderer> video_renderer( |
| 197 new media::VideoRendererBase( |
| 198 media_thread_.message_loop_proxy(), |
| 199 set_decryptor_ready_cb, |
| 200 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), |
| 201 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), |
| 202 true)); |
| 203 filter_collection_->SetVideoRenderer(video_renderer.Pass()); |
| 204 |
| 205 // Create default audio renderer using the null sink if no sink was provided. |
190 audio_source_provider_ = new WebAudioSourceProviderImpl( | 206 audio_source_provider_ = new WebAudioSourceProviderImpl( |
191 params.audio_renderer_sink() ? params.audio_renderer_sink() : | 207 params.audio_renderer_sink() ? params.audio_renderer_sink() : |
192 new media::NullAudioSink(media_thread_.message_loop_proxy())); | 208 new media::NullAudioSink(media_thread_.message_loop_proxy())); |
| 209 |
| 210 ScopedVector<media::AudioDecoder> audio_decoders; |
| 211 AddDefaultAudioDecoders(media_thread_.message_loop_proxy(), &audio_decoders); |
| 212 |
| 213 scoped_ptr<media::AudioRenderer> audio_renderer( |
| 214 new media::AudioRendererImpl( |
| 215 media_thread_.message_loop_proxy(), |
| 216 audio_source_provider_, |
| 217 audio_decoders.Pass(), |
| 218 set_decryptor_ready_cb)); |
| 219 filter_collection_->SetAudioRenderer(audio_renderer.Pass()); |
193 } | 220 } |
194 | 221 |
195 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 222 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
196 SetVideoFrameProviderClient(NULL); | 223 SetVideoFrameProviderClient(NULL); |
197 GetClient()->setWebLayer(NULL); | 224 GetClient()->setWebLayer(NULL); |
198 | 225 |
199 DCHECK(main_loop_->BelongsToCurrentThread()); | 226 DCHECK(main_loop_->BelongsToCurrentThread()); |
200 Destroy(); | 227 Destroy(); |
201 media_log_->AddEvent( | 228 media_log_->AddEvent( |
202 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 229 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 data_source_ = new BufferedDataSource( | 281 data_source_ = new BufferedDataSource( |
255 main_loop_, frame_, media_log_, base::Bind( | 282 main_loop_, frame_, media_log_, base::Bind( |
256 &WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr())); | 283 &WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr())); |
257 data_source_->Initialize( | 284 data_source_->Initialize( |
258 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 285 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
259 base::Bind( | 286 base::Bind( |
260 &WebMediaPlayerImpl::DataSourceInitialized, | 287 &WebMediaPlayerImpl::DataSourceInitialized, |
261 AsWeakPtr(), gurl)); | 288 AsWeakPtr(), gurl)); |
262 | 289 |
263 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 290 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |
| 291 |
| 292 BuildDefaultCollection( |
| 293 data_source_, |
| 294 media_thread_.message_loop_proxy(), |
| 295 filter_collection_.get(), |
| 296 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", "")); |
264 } | 297 } |
265 | 298 |
266 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, | 299 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, |
267 WebKit::WebMediaSource* media_source, | 300 WebKit::WebMediaSource* media_source, |
268 CORSMode cors_mode) { | 301 CORSMode cors_mode) { |
269 scoped_ptr<WebKit::WebMediaSource> ms(media_source); | 302 scoped_ptr<WebKit::WebMediaSource> ms(media_source); |
270 LoadSetup(url); | 303 LoadSetup(url); |
271 | 304 |
272 // Media source pipelines can start immediately. | 305 // Media source pipelines can start immediately. |
273 chunk_demuxer_ = new media::ChunkDemuxer( | 306 chunk_demuxer_ = new media::ChunkDemuxer( |
274 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, | 307 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, |
275 base::Passed(&ms)), | 308 base::Passed(&ms)), |
276 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), | 309 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), |
277 base::Bind(&LogMediaSourceError, media_log_)); | 310 base::Bind(&LogMediaSourceError, media_log_)); |
278 | 311 |
| 312 BuildMediaSourceCollection(chunk_demuxer_, |
| 313 media_thread_.message_loop_proxy(), |
| 314 filter_collection_.get()); |
279 supports_save_ = false; | 315 supports_save_ = false; |
280 StartPipeline(); | 316 StartPipeline(); |
281 } | 317 } |
282 | 318 |
283 void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) { | 319 void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) { |
284 GURL gurl(url); | 320 GURL gurl(url); |
285 UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(gurl), kMaxURLScheme); | 321 UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(gurl), kMaxURLScheme); |
286 | 322 |
287 // Set subresource URL for crash reporting. | 323 // Set subresource URL for crash reporting. |
288 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); | 324 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 1168 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
1133 media_log_->AddEvent( | 1169 media_log_->AddEvent( |
1134 media_log_->CreateBooleanEvent( | 1170 media_log_->CreateBooleanEvent( |
1135 media::MediaLogEvent::NETWORK_ACTIVITY_SET, | 1171 media::MediaLogEvent::NETWORK_ACTIVITY_SET, |
1136 "is_downloading_data", is_downloading)); | 1172 "is_downloading_data", is_downloading)); |
1137 } | 1173 } |
1138 | 1174 |
1139 void WebMediaPlayerImpl::StartPipeline() { | 1175 void WebMediaPlayerImpl::StartPipeline() { |
1140 starting_ = true; | 1176 starting_ = true; |
1141 pipeline_->Start( | 1177 pipeline_->Start( |
1142 BuildFilterCollection(), | 1178 filter_collection_.Pass(), |
1143 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | 1179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
1144 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), | 1180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
1145 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), | 1181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), |
1146 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), | 1182 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), |
1147 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); | 1183 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); |
1148 } | 1184 } |
1149 | 1185 |
1150 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1186 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1151 DCHECK(main_loop_->BelongsToCurrentThread()); | 1187 DCHECK(main_loop_->BelongsToCurrentThread()); |
1152 DVLOG(1) << "SetNetworkState: " << state; | 1188 DVLOG(1) << "SetNetworkState: " << state; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 current_frame_ = frame; | 1279 current_frame_ = frame; |
1244 | 1280 |
1245 if (pending_repaint_) | 1281 if (pending_repaint_) |
1246 return; | 1282 return; |
1247 | 1283 |
1248 pending_repaint_ = true; | 1284 pending_repaint_ = true; |
1249 main_loop_->PostTask(FROM_HERE, base::Bind( | 1285 main_loop_->PostTask(FROM_HERE, base::Bind( |
1250 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); | 1286 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); |
1251 } | 1287 } |
1252 | 1288 |
1253 scoped_ptr<media::FilterCollection> | |
1254 WebMediaPlayerImpl::BuildFilterCollection() { | |
1255 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | |
1256 | |
1257 scoped_ptr<media::FilterCollection> filter_collection( | |
1258 new media::FilterCollection()); | |
1259 | |
1260 // Figure out which demuxer to use. | |
1261 if (data_source_) { | |
1262 DCHECK(!chunk_demuxer_); | |
1263 filter_collection->SetDemuxer(new media::FFmpegDemuxer( | |
1264 media_thread_.message_loop_proxy(), data_source_, | |
1265 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""))); | |
1266 } else { | |
1267 DCHECK(chunk_demuxer_); | |
1268 filter_collection->SetDemuxer(chunk_demuxer_); | |
1269 | |
1270 // Disable GpuVideoDecoder creation until it supports codec config changes. | |
1271 // TODO(acolwell): Remove this once http://crbug.com/151045 is fixed. | |
1272 gpu_factories_ = NULL; | |
1273 } | |
1274 | |
1275 // Figure out if EME is enabled. | |
1276 media::SetDecryptorReadyCB set_decryptor_ready_cb; | |
1277 if (decryptor_) { | |
1278 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB, | |
1279 base::Unretained(decryptor_.get())); | |
1280 } | |
1281 | |
1282 // Create our audio decoders and renderer. | |
1283 ScopedVector<media::AudioDecoder> audio_decoders; | |
1284 audio_decoders.push_back(new media::FFmpegAudioDecoder( | |
1285 media_thread_.message_loop_proxy())); | |
1286 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { | |
1287 audio_decoders.push_back(new media::OpusAudioDecoder( | |
1288 media_thread_.message_loop_proxy())); | |
1289 } | |
1290 | |
1291 scoped_ptr<media::AudioRenderer> audio_renderer( | |
1292 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), | |
1293 audio_source_provider_, | |
1294 audio_decoders.Pass(), | |
1295 set_decryptor_ready_cb)); | |
1296 filter_collection->SetAudioRenderer(audio_renderer.Pass()); | |
1297 | |
1298 // Create our video decoders and renderer. | |
1299 ScopedVector<media::VideoDecoder> video_decoders; | |
1300 | |
1301 if (gpu_factories_) { | |
1302 video_decoders.push_back(new media::GpuVideoDecoder( | |
1303 media_thread_.message_loop_proxy(), gpu_factories_)); | |
1304 } | |
1305 | |
1306 video_decoders.push_back(new media::FFmpegVideoDecoder( | |
1307 media_thread_.message_loop_proxy())); | |
1308 | |
1309 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released | |
1310 // (http://crbug.com/174287) . | |
1311 #if !defined(MEDIA_DISABLE_LIBVPX) | |
1312 if (cmd_line->HasSwitch(switches::kEnableVp9Playback)) { | |
1313 video_decoders.push_back(new media::VpxVideoDecoder( | |
1314 media_thread_.message_loop_proxy())); | |
1315 } | |
1316 #endif // !defined(MEDIA_DISABLE_LIBVPX) | |
1317 | |
1318 scoped_ptr<media::VideoRenderer> video_renderer( | |
1319 new media::VideoRendererBase( | |
1320 media_thread_.message_loop_proxy(), | |
1321 video_decoders.Pass(), | |
1322 set_decryptor_ready_cb, | |
1323 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), | |
1324 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), | |
1325 true)); | |
1326 filter_collection->SetVideoRenderer(video_renderer.Pass()); | |
1327 | |
1328 return filter_collection.Pass(); | |
1329 } | |
1330 | |
1331 } // namespace webkit_media | 1289 } // namespace webkit_media |
OLD | NEW |