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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 pending_seek_seconds_(0.0f), | 146 pending_seek_seconds_(0.0f), |
147 client_(client), | 147 client_(client), |
148 delegate_(delegate), | 148 delegate_(delegate), |
149 media_log_(params.media_log()), | 149 media_log_(params.media_log()), |
150 accelerated_compositing_reported_(false), | 150 accelerated_compositing_reported_(false), |
151 incremented_externally_allocated_memory_(false), | 151 incremented_externally_allocated_memory_(false), |
152 gpu_factories_(params.gpu_factories()), | 152 gpu_factories_(params.gpu_factories()), |
153 is_local_source_(false), | 153 is_local_source_(false), |
154 supports_save_(true), | 154 supports_save_(true), |
155 starting_(false), | 155 starting_(false), |
156 chunk_demuxer_(NULL), | |
156 pending_repaint_(false), | 157 pending_repaint_(false), |
157 video_frame_provider_client_(NULL) { | 158 video_frame_provider_client_(NULL) { |
158 media_log_->AddEvent( | 159 media_log_->AddEvent( |
159 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 160 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
160 | 161 |
161 CHECK(media_thread_.Start()); | 162 CHECK(media_thread_.Start()); |
162 pipeline_ = new media::Pipeline( | 163 pipeline_ = new media::Pipeline( |
163 media_thread_.message_loop_proxy(), media_log_); | 164 media_thread_.message_loop_proxy(), media_log_); |
164 | 165 |
165 // Let V8 know we started new thread if we did not do it yet. | 166 // Let V8 know we started new thread if we did not do it yet. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 base::Bind( | 260 base::Bind( |
260 &WebMediaPlayerImpl::DataSourceInitialized, | 261 &WebMediaPlayerImpl::DataSourceInitialized, |
261 AsWeakPtr(), gurl)); | 262 AsWeakPtr(), gurl)); |
262 | 263 |
263 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 264 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |
264 } | 265 } |
265 | 266 |
266 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, | 267 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, |
267 WebKit::WebMediaSource* media_source, | 268 WebKit::WebMediaSource* media_source, |
268 CORSMode cors_mode) { | 269 CORSMode cors_mode) { |
269 scoped_ptr<WebKit::WebMediaSource> ms(media_source); | |
scherkus (not reviewing)
2013/04/19 23:18:45
this was the source of the crash -- ms would go ou
| |
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 824 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 | |
1137 // Figure out which demuxer to use. | |
1138 if (!media_source) { | |
1139 DCHECK(!chunk_demuxer_); | |
1140 DCHECK(data_source_); | |
1141 | |
1142 demuxer_.reset(new media::FFmpegDemuxer( | |
1143 media_thread_.message_loop_proxy(), data_source_, | |
1144 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""))); | |
1145 } else { | |
1146 DCHECK(!chunk_demuxer_); | |
1147 DCHECK(!data_source_); | |
1148 | |
1149 scoped_ptr<WebKit::WebMediaSource> ms(media_source); | |
1150 chunk_demuxer_ = new media::ChunkDemuxer( | |
1151 BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened, | |
1152 base::Passed(&ms)), | |
1153 BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""), | |
1154 base::Bind(&LogMediaSourceError, media_log_)); | |
1155 demuxer_.reset(chunk_demuxer_); | |
1156 | |
1157 // Disable GpuVideoDecoder creation until it supports codec config changes. | |
1158 // TODO(acolwell): Remove this once http://crbug.com/151045 is fixed. | |
1159 gpu_factories_ = NULL; | |
1160 } | |
1161 | |
1162 scoped_ptr<media::FilterCollection> filter_collection( | |
1163 new media::FilterCollection()); | |
1164 filter_collection->SetDemuxer(demuxer_.get()); | |
1165 | |
1166 // Figure out if EME is enabled. | |
1167 media::SetDecryptorReadyCB set_decryptor_ready_cb; | |
1168 if (decryptor_) { | |
1169 set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB, | |
1170 base::Unretained(decryptor_.get())); | |
1171 } | |
1172 | |
1173 // Create our audio decoders and renderer. | |
1174 ScopedVector<media::AudioDecoder> audio_decoders; | |
1175 audio_decoders.push_back(new media::FFmpegAudioDecoder( | |
1176 media_thread_.message_loop_proxy())); | |
1177 if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { | |
1178 audio_decoders.push_back(new media::OpusAudioDecoder( | |
1179 media_thread_.message_loop_proxy())); | |
1180 } | |
1181 | |
1182 scoped_ptr<media::AudioRenderer> audio_renderer( | |
1183 new media::AudioRendererImpl(media_thread_.message_loop_proxy(), | |
1184 audio_source_provider_, | |
1185 audio_decoders.Pass(), | |
1186 set_decryptor_ready_cb)); | |
1187 filter_collection->SetAudioRenderer(audio_renderer.Pass()); | |
1188 | |
1189 // Create our video decoders and renderer. | |
1190 ScopedVector<media::VideoDecoder> video_decoders; | |
1191 | |
1192 if (gpu_factories_) { | |
1193 video_decoders.push_back(new media::GpuVideoDecoder( | |
1194 media_thread_.message_loop_proxy(), gpu_factories_)); | |
1195 } | |
1196 | |
1197 video_decoders.push_back(new media::FFmpegVideoDecoder( | |
1198 media_thread_.message_loop_proxy())); | |
1199 | |
1200 // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released | |
1201 // (http://crbug.com/174287) . | |
1202 #if !defined(MEDIA_DISABLE_LIBVPX) | |
1203 if (cmd_line->HasSwitch(switches::kEnableVp9Playback)) { | |
1204 video_decoders.push_back(new media::VpxVideoDecoder( | |
1205 media_thread_.message_loop_proxy())); | |
1206 } | |
1207 #endif // !defined(MEDIA_DISABLE_LIBVPX) | |
1208 | |
1209 scoped_ptr<media::VideoRenderer> video_renderer( | |
1210 new media::VideoRendererBase( | |
1211 media_thread_.message_loop_proxy(), | |
1212 video_decoders.Pass(), | |
1213 set_decryptor_ready_cb, | |
1214 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), | |
1215 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), | |
1216 true)); | |
1217 filter_collection->SetVideoRenderer(video_renderer.Pass()); | |
1218 | |
1219 // ... and we're ready to go! | |
1140 starting_ = true; | 1220 starting_ = true; |
1141 pipeline_->Start( | 1221 pipeline_->Start( |
1142 BuildFilterCollection(), | 1222 filter_collection.Pass(), |
1143 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | 1223 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
1144 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), | 1224 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
1145 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), | 1225 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), |
1146 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), | 1226 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState), |
1147 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); | 1227 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange)); |
1148 } | 1228 } |
1149 | 1229 |
1150 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1230 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1151 DCHECK(main_loop_->BelongsToCurrentThread()); | 1231 DCHECK(main_loop_->BelongsToCurrentThread()); |
1152 DVLOG(1) << "SetNetworkState: " << state; | 1232 DVLOG(1) << "SetNetworkState: " << state; |
(...skipping 15 matching lines...) Expand all Loading... | |
1168 // Always notify to ensure client has the latest value. | 1248 // Always notify to ensure client has the latest value. |
1169 GetClient()->readyStateChanged(); | 1249 GetClient()->readyStateChanged(); |
1170 } | 1250 } |
1171 | 1251 |
1172 void WebMediaPlayerImpl::Destroy() { | 1252 void WebMediaPlayerImpl::Destroy() { |
1173 DCHECK(main_loop_->BelongsToCurrentThread()); | 1253 DCHECK(main_loop_->BelongsToCurrentThread()); |
1174 | 1254 |
1175 // Abort any pending IO so stopping the pipeline doesn't get blocked. | 1255 // Abort any pending IO so stopping the pipeline doesn't get blocked. |
1176 if (data_source_) | 1256 if (data_source_) |
1177 data_source_->Abort(); | 1257 data_source_->Abort(); |
1178 if (chunk_demuxer_) | 1258 if (chunk_demuxer_) { |
1179 chunk_demuxer_->Shutdown(); | 1259 chunk_demuxer_->Shutdown(); |
1260 chunk_demuxer_ = NULL; | |
1261 } | |
1180 | 1262 |
1181 if (gpu_factories_) { | 1263 if (gpu_factories_) { |
1182 gpu_factories_->Abort(); | 1264 gpu_factories_->Abort(); |
1183 gpu_factories_ = NULL; | 1265 gpu_factories_ = NULL; |
1184 } | 1266 } |
1185 | 1267 |
1186 // Make sure to kill the pipeline so there's no more media threads running. | 1268 // Make sure to kill the pipeline so there's no more media threads running. |
1187 // Note: stopping the pipeline might block for a long time. | 1269 // Note: stopping the pipeline might block for a long time. |
1188 base::WaitableEvent waiter(false, false); | 1270 base::WaitableEvent waiter(false, false); |
1189 pipeline_->Stop(base::Bind( | 1271 pipeline_->Stop(base::Bind( |
1190 &base::WaitableEvent::Signal, base::Unretained(&waiter))); | 1272 &base::WaitableEvent::Signal, base::Unretained(&waiter))); |
1191 waiter.Wait(); | 1273 waiter.Wait(); |
1192 | 1274 |
1193 // Let V8 know we are not using extra resources anymore. | 1275 // Let V8 know we are not using extra resources anymore. |
1194 if (incremented_externally_allocated_memory_) { | 1276 if (incremented_externally_allocated_memory_) { |
1195 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); | 1277 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); |
1196 incremented_externally_allocated_memory_ = false; | 1278 incremented_externally_allocated_memory_ = false; |
1197 } | 1279 } |
1198 | 1280 |
1199 media_thread_.Stop(); | 1281 media_thread_.Stop(); |
1200 | 1282 |
1201 // Release any final references now that everything has stopped. | 1283 // Release any final references now that everything has stopped. |
1202 data_source_ = NULL; | 1284 data_source_ = NULL; |
1203 chunk_demuxer_ = NULL; | 1285 demuxer_.reset(); |
1204 } | 1286 } |
1205 | 1287 |
1206 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 1288 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |
1207 DCHECK(main_loop_->BelongsToCurrentThread()); | 1289 DCHECK(main_loop_->BelongsToCurrentThread()); |
1208 DCHECK(client_); | 1290 DCHECK(client_); |
1209 return client_; | 1291 return client_; |
1210 } | 1292 } |
1211 | 1293 |
1212 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 1294 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |
1213 return audio_source_provider_; | 1295 return audio_source_provider_; |
(...skipping 29 matching lines...) Expand all Loading... | |
1243 current_frame_ = frame; | 1325 current_frame_ = frame; |
1244 | 1326 |
1245 if (pending_repaint_) | 1327 if (pending_repaint_) |
1246 return; | 1328 return; |
1247 | 1329 |
1248 pending_repaint_ = true; | 1330 pending_repaint_ = true; |
1249 main_loop_->PostTask(FROM_HERE, base::Bind( | 1331 main_loop_->PostTask(FROM_HERE, base::Bind( |
1250 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); | 1332 &WebMediaPlayerImpl::Repaint, AsWeakPtr())); |
1251 } | 1333 } |
1252 | 1334 |
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 | 1335 } // namespace webkit_media |
OLD | NEW |