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> |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 263 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |
264 } | 264 } |
265 | 265 |
266 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, | 266 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, |
267 WebKit::WebMediaSource* media_source, | 267 WebKit::WebMediaSource* media_source, |
268 CORSMode cors_mode) { | 268 CORSMode cors_mode) { |
269 scoped_ptr<WebKit::WebMediaSource> ms(media_source); | 269 scoped_ptr<WebKit::WebMediaSource> ms(media_source); |
270 LoadSetup(url); | 270 LoadSetup(url); |
271 | 271 |
272 // Media source pipelines can start immediately. | 272 // Media source pipelines can start immediately. |
273 chunk_demuxer_ = new media::ChunkDemuxer( | |
274 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, | |
275 base::Passed(&ms)), | |
276 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), | |
277 base::Bind(&LogMediaSourceError, media_log_)); | |
278 | |
279 supports_save_ = false; | 273 supports_save_ = false; |
280 StartPipeline(); | 274 StartPipeline(media_source); |
281 } | 275 } |
282 | 276 |
283 void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) { | 277 void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) { |
284 GURL gurl(url); | 278 GURL gurl(url); |
285 UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(gurl), kMaxURLScheme); | 279 UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(gurl), kMaxURLScheme); |
286 | 280 |
287 // Set subresource URL for crash reporting. | 281 // Set subresource URL for crash reporting. |
288 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); | 282 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); |
289 | 283 |
290 // Handle any volume/preload changes that occurred before load(). | 284 // Handle any volume/preload changes that occurred before load(). |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 } | 1015 } |
1022 | 1016 |
1023 // Repaint to trigger UI update. | 1017 // Repaint to trigger UI update. |
1024 Repaint(); | 1018 Repaint(); |
1025 } | 1019 } |
1026 | 1020 |
1027 void WebMediaPlayerImpl::OnDemuxerOpened( | 1021 void WebMediaPlayerImpl::OnDemuxerOpened( |
1028 scoped_ptr<WebKit::WebMediaSource> media_source) { | 1022 scoped_ptr<WebKit::WebMediaSource> media_source) { |
1029 DCHECK(main_loop_->BelongsToCurrentThread()); | 1023 DCHECK(main_loop_->BelongsToCurrentThread()); |
1030 media_source->open(new WebMediaSourceClientImpl( | 1024 media_source->open(new WebMediaSourceClientImpl( |
1031 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); | 1025 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); |
1032 } | 1026 } |
1033 | 1027 |
1034 void WebMediaPlayerImpl::OnKeyAdded(const std::string& key_system, | 1028 void WebMediaPlayerImpl::OnKeyAdded(const std::string& key_system, |
1035 const std::string& session_id) { | 1029 const std::string& session_id) { |
1036 DCHECK(main_loop_->BelongsToCurrentThread()); | 1030 DCHECK(main_loop_->BelongsToCurrentThread()); |
1037 EmeUMAHistogramCounts(key_system, "KeyAdded", 1); | 1031 EmeUMAHistogramCounts(key_system, "KeyAdded", 1); |
1038 GetClient()->keyAdded(WebString::fromUTF8(key_system), | 1032 GetClient()->keyAdded(WebString::fromUTF8(key_system), |
1039 WebString::fromUTF8(session_id)); | 1033 WebString::fromUTF8(session_id)); |
1040 } | 1034 } |
1041 | 1035 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 | 1109 |
1116 void WebMediaPlayerImpl::DataSourceInitialized(const GURL& gurl, bool success) { | 1110 void WebMediaPlayerImpl::DataSourceInitialized(const GURL& gurl, bool success) { |
1117 DCHECK(main_loop_->BelongsToCurrentThread()); | 1111 DCHECK(main_loop_->BelongsToCurrentThread()); |
1118 | 1112 |
1119 if (!success) { | 1113 if (!success) { |
1120 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 1114 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
1121 Repaint(); | 1115 Repaint(); |
1122 return; | 1116 return; |
1123 } | 1117 } |
1124 | 1118 |
1125 StartPipeline(); | 1119 StartPipeline(NULL); |
1126 } | 1120 } |
1127 | 1121 |
1128 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { | 1122 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { |
1129 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading) | 1123 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading) |
1130 SetNetworkState(WebMediaPlayer::NetworkStateIdle); | 1124 SetNetworkState(WebMediaPlayer::NetworkStateIdle); |
1131 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) | 1125 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) |
1132 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 1126 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
1133 media_log_->AddEvent( | 1127 media_log_->AddEvent( |
1134 media_log_->CreateBooleanEvent( | 1128 media_log_->CreateBooleanEvent( |
1135 media::MediaLogEvent::NETWORK_ACTIVITY_SET, | 1129 media::MediaLogEvent::NETWORK_ACTIVITY_SET, |
1136 "is_downloading_data", is_downloading)); | 1130 "is_downloading_data", is_downloading)); |
1137 } | 1131 } |
1138 | 1132 |
1139 void WebMediaPlayerImpl::StartPipeline() { | 1133 void WebMediaPlayerImpl::StartPipeline(WebKit::WebMediaSource* media_source) { |
| 1134 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 1135 |
| 1136 scoped_ptr<media::FilterCollection> filter_collection( |
| 1137 new media::FilterCollection()); |
| 1138 |
| 1139 // Figure out which demuxer to use. |
| 1140 if (!media_source) { |
| 1141 DCHECK(!chunk_demuxer_); |
| 1142 DCHECK(data_source_); |
| 1143 |
| 1144 ffmpeg_demuxer_.reset(new media::FFmpegDemuxer( |
| 1145 media_thread_.message_loop_proxy(), data_source_, |
| 1146 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""))); |
| 1147 filter_collection->SetDemuxer(ffmpeg_demuxer_.get()); |
| 1148 } else { |
| 1149 DCHECK(!chunk_demuxer_); |
| 1150 DCHECK(!data_source_); |
| 1151 |
| 1152 scoped_ptr<WebKit::WebMediaSource> ms(media_source); |
| 1153 chunk_demuxer_.reset(new media::ChunkDemuxer( |
| 1154 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, |
| 1155 base::Passed(&ms)), |
| 1156 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), |
| 1157 base::Bind(&LogMediaSourceError, media_log_))); |
| 1158 filter_collection->SetDemuxer(chunk_demuxer_.get()); |
| 1159 |
| 1160 // Disable GpuVideoDecoder creation until it supports codec config changes. |
| 1161 // TODO(acolwell): Remove this once http://crbug.com/151045 is fixed. |
| 1162 gpu_factories_ = NULL; |
| 1163 } |
| 1164 |
| 1165 // Figure out if EME is enabled. |
| 1166 media::SetDecryptorReadyCB set_decryptor_ready_cb; |
| 1167 if (decryptor_) { |
| 1168 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB, |
| 1169 base::Unretained(decryptor_.get())); |
| 1170 } |
| 1171 |
| 1172 // Create our audio decoders and renderer. |
| 1173 ScopedVector<media::AudioDecoder> audio_decoders; |
| 1174 audio_decoders.push_back(new media::FFmpegAudioDecoder( |
| 1175 media_thread_.message_loop_proxy())); |
| 1176 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { |
| 1177 audio_decoders.push_back(new media::OpusAudioDecoder( |
| 1178 media_thread_.message_loop_proxy())); |
| 1179 } |
| 1180 |
| 1181 scoped_ptr<media::AudioRenderer> audio_renderer( |
| 1182 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), |
| 1183 audio_source_provider_, |
| 1184 audio_decoders.Pass(), |
| 1185 set_decryptor_ready_cb)); |
| 1186 filter_collection->SetAudioRenderer(audio_renderer.Pass()); |
| 1187 |
| 1188 // Create our video decoders and renderer. |
| 1189 ScopedVector<media::VideoDecoder> video_decoders; |
| 1190 |
| 1191 if (gpu_factories_) { |
| 1192 video_decoders.push_back(new media::GpuVideoDecoder( |
| 1193 media_thread_.message_loop_proxy(), gpu_factories_)); |
| 1194 } |
| 1195 |
| 1196 video_decoders.push_back(new media::FFmpegVideoDecoder( |
| 1197 media_thread_.message_loop_proxy())); |
| 1198 |
| 1199 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released |
| 1200 // (http://crbug.com/174287) . |
| 1201 #if !defined(MEDIA_DISABLE_LIBVPX) |
| 1202 if (cmd_line->HasSwitch(switches::kEnableVp9Playback)) { |
| 1203 video_decoders.push_back(new media::VpxVideoDecoder( |
| 1204 media_thread_.message_loop_proxy())); |
| 1205 } |
| 1206 #endif // !defined(MEDIA_DISABLE_LIBVPX) |
| 1207 |
| 1208 scoped_ptr<media::VideoRenderer> video_renderer( |
| 1209 new media::VideoRendererBase( |
| 1210 media_thread_.message_loop_proxy(), |
| 1211 video_decoders.Pass(), |
| 1212 set_decryptor_ready_cb, |
| 1213 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), |
| 1214 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), |
| 1215 true)); |
| 1216 filter_collection->SetVideoRenderer(video_renderer.Pass()); |
| 1217 |
| 1218 // ... and we're ready to go! |
1140 starting_ = true; | 1219 starting_ = true; |
1141 pipeline_->Start( | 1220 pipeline_->Start( |
1142 BuildFilterCollection(), | 1221 filter_collection.Pass(), |
1143 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | 1222 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
1144 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), | 1223 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
1145 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), | 1224 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), |
1146 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), | 1225 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), |
1147 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); | 1226 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); |
1148 } | 1227 } |
1149 | 1228 |
1150 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1229 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1151 DCHECK(main_loop_->BelongsToCurrentThread()); | 1230 DCHECK(main_loop_->BelongsToCurrentThread()); |
1152 DVLOG(1) << "SetNetworkState: " << state; | 1231 DVLOG(1) << "SetNetworkState: " << state; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 // Let V8 know we are not using extra resources anymore. | 1272 // Let V8 know we are not using extra resources anymore. |
1194 if (incremented_externally_allocated_memory_) { | 1273 if (incremented_externally_allocated_memory_) { |
1195 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); | 1274 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); |
1196 incremented_externally_allocated_memory_ = false; | 1275 incremented_externally_allocated_memory_ = false; |
1197 } | 1276 } |
1198 | 1277 |
1199 media_thread_.Stop(); | 1278 media_thread_.Stop(); |
1200 | 1279 |
1201 // Release any final references now that everything has stopped. | 1280 // Release any final references now that everything has stopped. |
1202 data_source_ = NULL; | 1281 data_source_ = NULL; |
1203 chunk_demuxer_ = NULL; | 1282 ffmpeg_demuxer_.reset(); |
| 1283 chunk_demuxer_.reset(); |
1204 } | 1284 } |
1205 | 1285 |
1206 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 1286 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |
1207 DCHECK(main_loop_->BelongsToCurrentThread()); | 1287 DCHECK(main_loop_->BelongsToCurrentThread()); |
1208 DCHECK(client_); | 1288 DCHECK(client_); |
1209 return client_; | 1289 return client_; |
1210 } | 1290 } |
1211 | 1291 |
1212 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 1292 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |
1213 return audio_source_provider_; | 1293 return audio_source_provider_; |
(...skipping 29 matching lines...) Expand all Loading... |
1243 current_frame_ = frame; | 1323 current_frame_ = frame; |
1244 | 1324 |
1245 if (pending_repaint_) | 1325 if (pending_repaint_) |
1246 return; | 1326 return; |
1247 | 1327 |
1248 pending_repaint_ = true; | 1328 pending_repaint_ = true; |
1249 main_loop_->PostTask(FROM_HERE, base::Bind( | 1329 main_loop_->PostTask(FROM_HERE, base::Bind( |
1250 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); | 1330 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); |
1251 } | 1331 } |
1252 | 1332 |
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 | 1333 } // namespace webkit_media |
OLD | NEW |