| 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> |
| 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/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
| 17 #include "base/debug/crash_logging.h" | 17 #include "base/debug/crash_logging.h" |
| 18 #include "base/debug/trace_event.h" | 18 #include "base/debug/trace_event.h" |
| 19 #include "base/message_loop/message_loop_proxy.h" | 19 #include "base/message_loop/message_loop_proxy.h" |
| 20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 21 #include "base/single_thread_task_runner.h" |
| 21 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
| 22 #include "cc/blink/web_layer_impl.h" | 23 #include "cc/blink/web_layer_impl.h" |
| 23 #include "cc/layers/video_layer.h" | 24 #include "cc/layers/video_layer.h" |
| 24 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
| 25 #include "content/public/renderer/render_frame.h" | 26 #include "content/public/renderer/render_frame.h" |
| 26 #include "content/renderer/media/buffered_data_source.h" | 27 #include "content/renderer/media/buffered_data_source.h" |
| 27 #include "content/renderer/media/crypto/encrypted_media_player_support.h" | 28 #include "content/renderer/media/crypto/encrypted_media_player_support.h" |
| 28 #include "content/renderer/media/render_media_log.h" | 29 #include "content/renderer/media/render_media_log.h" |
| 29 #include "content/renderer/media/texttrack_impl.h" | 30 #include "content/renderer/media/texttrack_impl.h" |
| 30 #include "content/renderer/media/webaudiosourceprovider_impl.h" | 31 #include "content/renderer/media/webaudiosourceprovider_impl.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ | 132 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ |
| 132 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ | 133 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ |
| 133 static_cast<int>(BufferedResourceLoader::k ## name), \ | 134 static_cast<int>(BufferedResourceLoader::k ## name), \ |
| 134 mismatching_enums) | 135 mismatching_enums) |
| 135 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); | 136 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); |
| 136 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); | 137 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); |
| 137 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); | 138 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); |
| 138 #undef COMPILE_ASSERT_MATCHING_ENUM | 139 #undef COMPILE_ASSERT_MATCHING_ENUM |
| 139 | 140 |
| 140 #define BIND_TO_RENDER_LOOP(function) \ | 141 #define BIND_TO_RENDER_LOOP(function) \ |
| 141 (DCHECK(main_loop_->BelongsToCurrentThread()), \ | 142 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
| 142 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) | 143 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) |
| 143 | 144 |
| 144 #define BIND_TO_RENDER_LOOP1(function, arg1) \ | 145 #define BIND_TO_RENDER_LOOP1(function, arg1) \ |
| 145 (DCHECK(main_loop_->BelongsToCurrentThread()), \ | 146 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
| 146 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) | 147 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) |
| 147 | 148 |
| 148 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, | 149 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, |
| 149 const std::string& error) { | 150 const std::string& error) { |
| 150 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); | 151 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); |
| 151 } | 152 } |
| 152 | 153 |
| 153 WebMediaPlayerImpl::WebMediaPlayerImpl( | 154 WebMediaPlayerImpl::WebMediaPlayerImpl( |
| 154 blink::WebLocalFrame* frame, | 155 blink::WebLocalFrame* frame, |
| 155 blink::WebMediaPlayerClient* client, | 156 blink::WebMediaPlayerClient* client, |
| 156 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 157 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
| 157 const WebMediaPlayerParams& params) | 158 const WebMediaPlayerParams& params) |
| 158 : frame_(frame), | 159 : frame_(frame), |
| 159 network_state_(WebMediaPlayer::NetworkStateEmpty), | 160 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 160 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 161 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 161 preload_(AUTO), | 162 preload_(AUTO), |
| 162 main_loop_(base::MessageLoopProxy::current()), | 163 main_task_runner_(base::MessageLoopProxy::current()), |
| 163 media_loop_( | 164 media_task_runner_( |
| 164 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), | 165 RenderThreadImpl::current()->GetMediaThreadTaskRunner()), |
| 165 media_log_(new RenderMediaLog()), | 166 media_log_(new RenderMediaLog()), |
| 166 pipeline_(media_loop_, media_log_.get()), | 167 pipeline_(media_task_runner_, media_log_.get()), |
| 167 load_type_(LoadTypeURL), | 168 load_type_(LoadTypeURL), |
| 168 opaque_(false), | 169 opaque_(false), |
| 169 paused_(true), | 170 paused_(true), |
| 170 seeking_(false), | 171 seeking_(false), |
| 171 playback_rate_(0.0f), | 172 playback_rate_(0.0f), |
| 172 pending_seek_(false), | 173 pending_seek_(false), |
| 173 pending_seek_seconds_(0.0f), | 174 pending_seek_seconds_(0.0f), |
| 174 should_notify_time_changed_(false), | 175 should_notify_time_changed_(false), |
| 175 client_(client), | 176 client_(client), |
| 176 delegate_(delegate), | 177 delegate_(delegate), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 191 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { | 192 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { |
| 192 DCHECK(encrypted_media_support_); | 193 DCHECK(encrypted_media_support_); |
| 193 | 194 |
| 194 media_log_->AddEvent( | 195 media_log_->AddEvent( |
| 195 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 196 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 196 | 197 |
| 197 // |gpu_factories_| requires that its entry points be called on its | 198 // |gpu_factories_| requires that its entry points be called on its |
| 198 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the | 199 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the |
| 199 // factories, require that their message loops are identical. | 200 // factories, require that their message loops are identical. |
| 200 DCHECK(!gpu_factories_.get() || | 201 DCHECK(!gpu_factories_.get() || |
| 201 (gpu_factories_->GetTaskRunner() == media_loop_.get())); | 202 (gpu_factories_->GetTaskRunner() == media_task_runner_.get())); |
| 202 | 203 |
| 203 // Let V8 know we started new thread if we did not do it yet. | 204 // 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 // 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 // Also, delaying GC until after player starts gets rid of starting lag -- |
| 206 // collection happens in parallel with playing. | 207 // collection happens in parallel with playing. |
| 207 // | 208 // |
| 208 // TODO(enal): remove when we get rid of per-audio-stream thread. | 209 // TODO(enal): remove when we get rid of per-audio-stream thread. |
| 209 main_loop_->PostTask( | 210 main_task_runner_->PostTask( |
| 210 FROM_HERE, | 211 FROM_HERE, |
| 211 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | 212 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, |
| 212 AsWeakPtr())); | 213 AsWeakPtr())); |
| 213 | 214 |
| 214 // Use the null sink if no sink was provided. | 215 // Use the null sink if no sink was provided. |
| 215 audio_source_provider_ = new WebAudioSourceProviderImpl( | 216 audio_source_provider_ = new WebAudioSourceProviderImpl( |
| 216 params.audio_renderer_sink().get() | 217 params.audio_renderer_sink().get() |
| 217 ? params.audio_renderer_sink() | 218 ? params.audio_renderer_sink() |
| 218 : new media::NullAudioSink(media_loop_)); | 219 : new media::NullAudioSink(media_task_runner_)); |
| 219 } | 220 } |
| 220 | 221 |
| 221 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 222 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
| 222 client_->setWebLayer(NULL); | 223 client_->setWebLayer(NULL); |
| 223 | 224 |
| 224 DCHECK(main_loop_->BelongsToCurrentThread()); | 225 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 225 media_log_->AddEvent( | 226 media_log_->AddEvent( |
| 226 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 227 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
| 227 | 228 |
| 228 if (delegate_.get()) | 229 if (delegate_.get()) |
| 229 delegate_->PlayerGone(this); | 230 delegate_->PlayerGone(this); |
| 230 | 231 |
| 231 // Abort any pending IO so stopping the pipeline doesn't get blocked. | 232 // Abort any pending IO so stopping the pipeline doesn't get blocked. |
| 232 if (data_source_) | 233 if (data_source_) |
| 233 data_source_->Abort(); | 234 data_source_->Abort(); |
| 234 if (chunk_demuxer_) { | 235 if (chunk_demuxer_) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 263 defer_load_cb_.Run(base::Bind( | 264 defer_load_cb_.Run(base::Bind( |
| 264 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); | 265 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); |
| 265 return; | 266 return; |
| 266 } | 267 } |
| 267 DoLoad(load_type, url, cors_mode); | 268 DoLoad(load_type, url, cors_mode); |
| 268 } | 269 } |
| 269 | 270 |
| 270 void WebMediaPlayerImpl::DoLoad(LoadType load_type, | 271 void WebMediaPlayerImpl::DoLoad(LoadType load_type, |
| 271 const blink::WebURL& url, | 272 const blink::WebURL& url, |
| 272 CORSMode cors_mode) { | 273 CORSMode cors_mode) { |
| 273 DCHECK(main_loop_->BelongsToCurrentThread()); | 274 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 274 | 275 |
| 275 GURL gurl(url); | 276 GURL gurl(url); |
| 276 ReportMediaSchemeUma(gurl); | 277 ReportMediaSchemeUma(gurl); |
| 277 | 278 |
| 278 // Set subresource URL for crash reporting. | 279 // Set subresource URL for crash reporting. |
| 279 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); | 280 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); |
| 280 | 281 |
| 281 load_type_ = load_type; | 282 load_type_ = load_type; |
| 282 | 283 |
| 283 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 284 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 284 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); | 285 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); |
| 285 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); | 286 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); |
| 286 | 287 |
| 287 // Media source pipelines can start immediately. | 288 // Media source pipelines can start immediately. |
| 288 if (load_type == LoadTypeMediaSource) { | 289 if (load_type == LoadTypeMediaSource) { |
| 289 supports_save_ = false; | 290 supports_save_ = false; |
| 290 StartPipeline(); | 291 StartPipeline(); |
| 291 return; | 292 return; |
| 292 } | 293 } |
| 293 | 294 |
| 294 // Otherwise it's a regular request which requires resolving the URL first. | 295 // Otherwise it's a regular request which requires resolving the URL first. |
| 295 data_source_.reset(new BufferedDataSource( | 296 data_source_.reset(new BufferedDataSource( |
| 296 url, | 297 url, |
| 297 static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 298 static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
| 298 main_loop_, | 299 main_task_runner_, |
| 299 frame_, | 300 frame_, |
| 300 media_log_.get(), | 301 media_log_.get(), |
| 301 &buffered_data_source_host_, | 302 &buffered_data_source_host_, |
| 302 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 303 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
| 303 data_source_->Initialize( | 304 data_source_->Initialize( |
| 304 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); | 305 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); |
| 305 data_source_->SetPreload(preload_); | 306 data_source_->SetPreload(preload_); |
| 306 } | 307 } |
| 307 | 308 |
| 308 void WebMediaPlayerImpl::play() { | 309 void WebMediaPlayerImpl::play() { |
| 309 DVLOG(1) << __FUNCTION__; | 310 DVLOG(1) << __FUNCTION__; |
| 310 DCHECK(main_loop_->BelongsToCurrentThread()); | 311 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 311 | 312 |
| 312 paused_ = false; | 313 paused_ = false; |
| 313 pipeline_.SetPlaybackRate(playback_rate_); | 314 pipeline_.SetPlaybackRate(playback_rate_); |
| 314 if (data_source_) | 315 if (data_source_) |
| 315 data_source_->MediaIsPlaying(); | 316 data_source_->MediaIsPlaying(); |
| 316 | 317 |
| 317 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); | 318 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); |
| 318 | 319 |
| 319 if (delegate_.get()) | 320 if (delegate_.get()) |
| 320 delegate_->DidPlay(this); | 321 delegate_->DidPlay(this); |
| 321 } | 322 } |
| 322 | 323 |
| 323 void WebMediaPlayerImpl::pause() { | 324 void WebMediaPlayerImpl::pause() { |
| 324 DVLOG(1) << __FUNCTION__; | 325 DVLOG(1) << __FUNCTION__; |
| 325 DCHECK(main_loop_->BelongsToCurrentThread()); | 326 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 326 | 327 |
| 327 paused_ = true; | 328 paused_ = true; |
| 328 pipeline_.SetPlaybackRate(0.0f); | 329 pipeline_.SetPlaybackRate(0.0f); |
| 329 if (data_source_) | 330 if (data_source_) |
| 330 data_source_->MediaIsPaused(); | 331 data_source_->MediaIsPaused(); |
| 331 paused_time_ = pipeline_.GetMediaTime(); | 332 paused_time_ = pipeline_.GetMediaTime(); |
| 332 | 333 |
| 333 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE)); | 334 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE)); |
| 334 | 335 |
| 335 if (delegate_.get()) | 336 if (delegate_.get()) |
| 336 delegate_->DidPause(this); | 337 delegate_->DidPause(this); |
| 337 } | 338 } |
| 338 | 339 |
| 339 bool WebMediaPlayerImpl::supportsSave() const { | 340 bool WebMediaPlayerImpl::supportsSave() const { |
| 340 DCHECK(main_loop_->BelongsToCurrentThread()); | 341 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 341 return supports_save_; | 342 return supports_save_; |
| 342 } | 343 } |
| 343 | 344 |
| 344 void WebMediaPlayerImpl::seek(double seconds) { | 345 void WebMediaPlayerImpl::seek(double seconds) { |
| 345 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; | 346 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; |
| 346 DCHECK(main_loop_->BelongsToCurrentThread()); | 347 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 347 | 348 |
| 348 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) | 349 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) |
| 349 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 350 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
| 350 | 351 |
| 351 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); | 352 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); |
| 352 | 353 |
| 353 if (seeking_) { | 354 if (seeking_) { |
| 354 pending_seek_ = true; | 355 pending_seek_ = true; |
| 355 pending_seek_seconds_ = seconds; | 356 pending_seek_seconds_ = seconds; |
| 356 if (chunk_demuxer_) | 357 if (chunk_demuxer_) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 370 chunk_demuxer_->StartWaitingForSeek(seek_time); | 371 chunk_demuxer_->StartWaitingForSeek(seek_time); |
| 371 | 372 |
| 372 // Kick off the asynchronous seek! | 373 // Kick off the asynchronous seek! |
| 373 pipeline_.Seek( | 374 pipeline_.Seek( |
| 374 seek_time, | 375 seek_time, |
| 375 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, true)); | 376 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, true)); |
| 376 } | 377 } |
| 377 | 378 |
| 378 void WebMediaPlayerImpl::setRate(double rate) { | 379 void WebMediaPlayerImpl::setRate(double rate) { |
| 379 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; | 380 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; |
| 380 DCHECK(main_loop_->BelongsToCurrentThread()); | 381 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 381 | 382 |
| 382 // TODO(kylep): Remove when support for negatives is added. Also, modify the | 383 // TODO(kylep): Remove when support for negatives is added. Also, modify the |
| 383 // following checks so rewind uses reasonable values also. | 384 // following checks so rewind uses reasonable values also. |
| 384 if (rate < 0.0) | 385 if (rate < 0.0) |
| 385 return; | 386 return; |
| 386 | 387 |
| 387 // Limit rates to reasonable values by clamping. | 388 // Limit rates to reasonable values by clamping. |
| 388 if (rate != 0.0) { | 389 if (rate != 0.0) { |
| 389 if (rate < kMinRate) | 390 if (rate < kMinRate) |
| 390 rate = kMinRate; | 391 rate = kMinRate; |
| 391 else if (rate > kMaxRate) | 392 else if (rate > kMaxRate) |
| 392 rate = kMaxRate; | 393 rate = kMaxRate; |
| 393 } | 394 } |
| 394 | 395 |
| 395 playback_rate_ = rate; | 396 playback_rate_ = rate; |
| 396 if (!paused_) { | 397 if (!paused_) { |
| 397 pipeline_.SetPlaybackRate(rate); | 398 pipeline_.SetPlaybackRate(rate); |
| 398 if (data_source_) | 399 if (data_source_) |
| 399 data_source_->MediaPlaybackRateChanged(rate); | 400 data_source_->MediaPlaybackRateChanged(rate); |
| 400 } | 401 } |
| 401 } | 402 } |
| 402 | 403 |
| 403 void WebMediaPlayerImpl::setVolume(double volume) { | 404 void WebMediaPlayerImpl::setVolume(double volume) { |
| 404 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; | 405 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; |
| 405 DCHECK(main_loop_->BelongsToCurrentThread()); | 406 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 406 | 407 |
| 407 pipeline_.SetVolume(volume); | 408 pipeline_.SetVolume(volume); |
| 408 } | 409 } |
| 409 | 410 |
| 410 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ | 411 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ |
| 411 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::webkit_name) == \ | 412 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::webkit_name) == \ |
| 412 static_cast<int>(content::chromium_name), \ | 413 static_cast<int>(content::chromium_name), \ |
| 413 mismatching_enums) | 414 mismatching_enums) |
| 414 COMPILE_ASSERT_MATCHING_ENUM(PreloadNone, NONE); | 415 COMPILE_ASSERT_MATCHING_ENUM(PreloadNone, NONE); |
| 415 COMPILE_ASSERT_MATCHING_ENUM(PreloadMetaData, METADATA); | 416 COMPILE_ASSERT_MATCHING_ENUM(PreloadMetaData, METADATA); |
| 416 COMPILE_ASSERT_MATCHING_ENUM(PreloadAuto, AUTO); | 417 COMPILE_ASSERT_MATCHING_ENUM(PreloadAuto, AUTO); |
| 417 #undef COMPILE_ASSERT_MATCHING_ENUM | 418 #undef COMPILE_ASSERT_MATCHING_ENUM |
| 418 | 419 |
| 419 void WebMediaPlayerImpl::setPreload(WebMediaPlayer::Preload preload) { | 420 void WebMediaPlayerImpl::setPreload(WebMediaPlayer::Preload preload) { |
| 420 DVLOG(1) << __FUNCTION__ << "(" << preload << ")"; | 421 DVLOG(1) << __FUNCTION__ << "(" << preload << ")"; |
| 421 DCHECK(main_loop_->BelongsToCurrentThread()); | 422 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 422 | 423 |
| 423 preload_ = static_cast<content::Preload>(preload); | 424 preload_ = static_cast<content::Preload>(preload); |
| 424 if (data_source_) | 425 if (data_source_) |
| 425 data_source_->SetPreload(preload_); | 426 data_source_->SetPreload(preload_); |
| 426 } | 427 } |
| 427 | 428 |
| 428 bool WebMediaPlayerImpl::hasVideo() const { | 429 bool WebMediaPlayerImpl::hasVideo() const { |
| 429 DCHECK(main_loop_->BelongsToCurrentThread()); | 430 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 430 | 431 |
| 431 return pipeline_metadata_.has_video; | 432 return pipeline_metadata_.has_video; |
| 432 } | 433 } |
| 433 | 434 |
| 434 bool WebMediaPlayerImpl::hasAudio() const { | 435 bool WebMediaPlayerImpl::hasAudio() const { |
| 435 DCHECK(main_loop_->BelongsToCurrentThread()); | 436 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 436 | 437 |
| 437 return pipeline_metadata_.has_audio; | 438 return pipeline_metadata_.has_audio; |
| 438 } | 439 } |
| 439 | 440 |
| 440 blink::WebSize WebMediaPlayerImpl::naturalSize() const { | 441 blink::WebSize WebMediaPlayerImpl::naturalSize() const { |
| 441 DCHECK(main_loop_->BelongsToCurrentThread()); | 442 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 442 | 443 |
| 443 return blink::WebSize(pipeline_metadata_.natural_size); | 444 return blink::WebSize(pipeline_metadata_.natural_size); |
| 444 } | 445 } |
| 445 | 446 |
| 446 bool WebMediaPlayerImpl::paused() const { | 447 bool WebMediaPlayerImpl::paused() const { |
| 447 DCHECK(main_loop_->BelongsToCurrentThread()); | 448 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 448 | 449 |
| 449 return pipeline_.GetPlaybackRate() == 0.0f; | 450 return pipeline_.GetPlaybackRate() == 0.0f; |
| 450 } | 451 } |
| 451 | 452 |
| 452 bool WebMediaPlayerImpl::seeking() const { | 453 bool WebMediaPlayerImpl::seeking() const { |
| 453 DCHECK(main_loop_->BelongsToCurrentThread()); | 454 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 454 | 455 |
| 455 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 456 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
| 456 return false; | 457 return false; |
| 457 | 458 |
| 458 return seeking_; | 459 return seeking_; |
| 459 } | 460 } |
| 460 | 461 |
| 461 double WebMediaPlayerImpl::duration() const { | 462 double WebMediaPlayerImpl::duration() const { |
| 462 DCHECK(main_loop_->BelongsToCurrentThread()); | 463 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 463 | 464 |
| 464 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 465 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
| 465 return std::numeric_limits<double>::quiet_NaN(); | 466 return std::numeric_limits<double>::quiet_NaN(); |
| 466 | 467 |
| 467 return GetPipelineDuration(); | 468 return GetPipelineDuration(); |
| 468 } | 469 } |
| 469 | 470 |
| 470 double WebMediaPlayerImpl::timelineOffset() const { | 471 double WebMediaPlayerImpl::timelineOffset() const { |
| 471 DCHECK(main_loop_->BelongsToCurrentThread()); | 472 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 472 | 473 |
| 473 if (pipeline_metadata_.timeline_offset.is_null()) | 474 if (pipeline_metadata_.timeline_offset.is_null()) |
| 474 return std::numeric_limits<double>::quiet_NaN(); | 475 return std::numeric_limits<double>::quiet_NaN(); |
| 475 | 476 |
| 476 return pipeline_metadata_.timeline_offset.ToJsTime(); | 477 return pipeline_metadata_.timeline_offset.ToJsTime(); |
| 477 } | 478 } |
| 478 | 479 |
| 479 double WebMediaPlayerImpl::currentTime() const { | 480 double WebMediaPlayerImpl::currentTime() const { |
| 480 DCHECK(main_loop_->BelongsToCurrentThread()); | 481 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 481 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); | 482 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); |
| 482 } | 483 } |
| 483 | 484 |
| 484 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { | 485 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { |
| 485 DCHECK(main_loop_->BelongsToCurrentThread()); | 486 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 486 return network_state_; | 487 return network_state_; |
| 487 } | 488 } |
| 488 | 489 |
| 489 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { | 490 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { |
| 490 DCHECK(main_loop_->BelongsToCurrentThread()); | 491 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 491 return ready_state_; | 492 return ready_state_; |
| 492 } | 493 } |
| 493 | 494 |
| 494 blink::WebTimeRanges WebMediaPlayerImpl::buffered() const { | 495 blink::WebTimeRanges WebMediaPlayerImpl::buffered() const { |
| 495 DCHECK(main_loop_->BelongsToCurrentThread()); | 496 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 496 | 497 |
| 497 media::Ranges<base::TimeDelta> buffered_time_ranges = | 498 media::Ranges<base::TimeDelta> buffered_time_ranges = |
| 498 pipeline_.GetBufferedTimeRanges(); | 499 pipeline_.GetBufferedTimeRanges(); |
| 499 | 500 |
| 500 const base::TimeDelta duration = pipeline_.GetMediaDuration(); | 501 const base::TimeDelta duration = pipeline_.GetMediaDuration(); |
| 501 if (duration != media::kInfiniteDuration()) { | 502 if (duration != media::kInfiniteDuration()) { |
| 502 buffered_data_source_host_.AddBufferedTimeRanges( | 503 buffered_data_source_host_.AddBufferedTimeRanges( |
| 503 &buffered_time_ranges, duration); | 504 &buffered_time_ranges, duration); |
| 504 } | 505 } |
| 505 return ConvertToWebTimeRanges(buffered_time_ranges); | 506 return ConvertToWebTimeRanges(buffered_time_ranges); |
| 506 } | 507 } |
| 507 | 508 |
| 508 double WebMediaPlayerImpl::maxTimeSeekable() const { | 509 double WebMediaPlayerImpl::maxTimeSeekable() const { |
| 509 DCHECK(main_loop_->BelongsToCurrentThread()); | 510 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 510 | 511 |
| 511 // If we haven't even gotten to ReadyStateHaveMetadata yet then just | 512 // If we haven't even gotten to ReadyStateHaveMetadata yet then just |
| 512 // return 0 so that the seekable range is empty. | 513 // return 0 so that the seekable range is empty. |
| 513 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) | 514 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) |
| 514 return 0.0; | 515 return 0.0; |
| 515 | 516 |
| 516 // We don't support seeking in streaming media. | 517 // We don't support seeking in streaming media. |
| 517 if (data_source_ && data_source_->IsStreaming()) | 518 if (data_source_ && data_source_->IsStreaming()) |
| 518 return 0.0; | 519 return 0.0; |
| 519 return duration(); | 520 return duration(); |
| 520 } | 521 } |
| 521 | 522 |
| 522 bool WebMediaPlayerImpl::didLoadingProgress() { | 523 bool WebMediaPlayerImpl::didLoadingProgress() { |
| 523 DCHECK(main_loop_->BelongsToCurrentThread()); | 524 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 524 bool pipeline_progress = pipeline_.DidLoadingProgress(); | 525 bool pipeline_progress = pipeline_.DidLoadingProgress(); |
| 525 bool data_progress = buffered_data_source_host_.DidLoadingProgress(); | 526 bool data_progress = buffered_data_source_host_.DidLoadingProgress(); |
| 526 return pipeline_progress || data_progress; | 527 return pipeline_progress || data_progress; |
| 527 } | 528 } |
| 528 | 529 |
| 529 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, | 530 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, |
| 530 const blink::WebRect& rect, | 531 const blink::WebRect& rect, |
| 531 unsigned char alpha) { | 532 unsigned char alpha) { |
| 532 paint(canvas, rect, alpha, SkXfermode::kSrcOver_Mode); | 533 paint(canvas, rect, alpha, SkXfermode::kSrcOver_Mode); |
| 533 } | 534 } |
| 534 | 535 |
| 535 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, | 536 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, |
| 536 const blink::WebRect& rect, | 537 const blink::WebRect& rect, |
| 537 unsigned char alpha, | 538 unsigned char alpha, |
| 538 SkXfermode::Mode mode) { | 539 SkXfermode::Mode mode) { |
| 539 DCHECK(main_loop_->BelongsToCurrentThread()); | 540 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 540 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); | 541 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); |
| 541 | 542 |
| 542 // TODO(scherkus): Clarify paint() API contract to better understand when and | 543 // TODO(scherkus): Clarify paint() API contract to better understand when and |
| 543 // why it's being called. For example, today paint() is called when: | 544 // why it's being called. For example, today paint() is called when: |
| 544 // - We haven't reached HAVE_CURRENT_DATA and need to paint black | 545 // - We haven't reached HAVE_CURRENT_DATA and need to paint black |
| 545 // - We're painting to a canvas | 546 // - We're painting to a canvas |
| 546 // See http://crbug.com/341225 http://crbug.com/342621 for details. | 547 // See http://crbug.com/341225 http://crbug.com/342621 for details. |
| 547 scoped_refptr<media::VideoFrame> video_frame = | 548 scoped_refptr<media::VideoFrame> video_frame = |
| 548 GetCurrentFrameFromCompositor(); | 549 GetCurrentFrameFromCompositor(); |
| 549 | 550 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 567 if (data_source_) | 568 if (data_source_) |
| 568 return data_source_->DidPassCORSAccessCheck(); | 569 return data_source_->DidPassCORSAccessCheck(); |
| 569 return false; | 570 return false; |
| 570 } | 571 } |
| 571 | 572 |
| 572 double WebMediaPlayerImpl::mediaTimeForTimeValue(double timeValue) const { | 573 double WebMediaPlayerImpl::mediaTimeForTimeValue(double timeValue) const { |
| 573 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); | 574 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); |
| 574 } | 575 } |
| 575 | 576 |
| 576 unsigned WebMediaPlayerImpl::decodedFrameCount() const { | 577 unsigned WebMediaPlayerImpl::decodedFrameCount() const { |
| 577 DCHECK(main_loop_->BelongsToCurrentThread()); | 578 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 578 | 579 |
| 579 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 580 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 580 return stats.video_frames_decoded; | 581 return stats.video_frames_decoded; |
| 581 } | 582 } |
| 582 | 583 |
| 583 unsigned WebMediaPlayerImpl::droppedFrameCount() const { | 584 unsigned WebMediaPlayerImpl::droppedFrameCount() const { |
| 584 DCHECK(main_loop_->BelongsToCurrentThread()); | 585 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 585 | 586 |
| 586 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 587 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 587 return stats.video_frames_dropped; | 588 return stats.video_frames_dropped; |
| 588 } | 589 } |
| 589 | 590 |
| 590 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { | 591 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { |
| 591 DCHECK(main_loop_->BelongsToCurrentThread()); | 592 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 592 | 593 |
| 593 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 594 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 594 return stats.audio_bytes_decoded; | 595 return stats.audio_bytes_decoded; |
| 595 } | 596 } |
| 596 | 597 |
| 597 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { | 598 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { |
| 598 DCHECK(main_loop_->BelongsToCurrentThread()); | 599 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 599 | 600 |
| 600 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 601 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 601 return stats.video_bytes_decoded; | 602 return stats.video_bytes_decoded; |
| 602 } | 603 } |
| 603 | 604 |
| 604 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( | 605 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( |
| 605 blink::WebGraphicsContext3D* web_graphics_context, | 606 blink::WebGraphicsContext3D* web_graphics_context, |
| 606 unsigned int texture, | 607 unsigned int texture, |
| 607 unsigned int level, | 608 unsigned int level, |
| 608 unsigned int internal_format, | 609 unsigned int internal_format, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 | 652 |
| 652 SyncPointClientImpl client(web_graphics_context); | 653 SyncPointClientImpl client(web_graphics_context); |
| 653 video_frame->UpdateReleaseSyncPoint(&client); | 654 video_frame->UpdateReleaseSyncPoint(&client); |
| 654 return true; | 655 return true; |
| 655 } | 656 } |
| 656 | 657 |
| 657 WebMediaPlayer::MediaKeyException | 658 WebMediaPlayer::MediaKeyException |
| 658 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, | 659 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, |
| 659 const unsigned char* init_data, | 660 const unsigned char* init_data, |
| 660 unsigned init_data_length) { | 661 unsigned init_data_length) { |
| 661 DCHECK(main_loop_->BelongsToCurrentThread()); | 662 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 662 | 663 |
| 663 return encrypted_media_support_->GenerateKeyRequest( | 664 return encrypted_media_support_->GenerateKeyRequest( |
| 664 frame_, key_system, init_data, init_data_length); | 665 frame_, key_system, init_data, init_data_length); |
| 665 } | 666 } |
| 666 | 667 |
| 667 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( | 668 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( |
| 668 const WebString& key_system, | 669 const WebString& key_system, |
| 669 const unsigned char* key, | 670 const unsigned char* key, |
| 670 unsigned key_length, | 671 unsigned key_length, |
| 671 const unsigned char* init_data, | 672 const unsigned char* init_data, |
| 672 unsigned init_data_length, | 673 unsigned init_data_length, |
| 673 const WebString& session_id) { | 674 const WebString& session_id) { |
| 674 DCHECK(main_loop_->BelongsToCurrentThread()); | 675 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 675 | 676 |
| 676 return encrypted_media_support_->AddKey( | 677 return encrypted_media_support_->AddKey( |
| 677 key_system, key, key_length, init_data, init_data_length, session_id); | 678 key_system, key, key_length, init_data, init_data_length, session_id); |
| 678 } | 679 } |
| 679 | 680 |
| 680 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( | 681 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( |
| 681 const WebString& key_system, | 682 const WebString& key_system, |
| 682 const WebString& session_id) { | 683 const WebString& session_id) { |
| 683 DCHECK(main_loop_->BelongsToCurrentThread()); | 684 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 684 | 685 |
| 685 return encrypted_media_support_->CancelKeyRequest(key_system, session_id); | 686 return encrypted_media_support_->CancelKeyRequest(key_system, session_id); |
| 686 } | 687 } |
| 687 | 688 |
| 688 void WebMediaPlayerImpl::setContentDecryptionModule( | 689 void WebMediaPlayerImpl::setContentDecryptionModule( |
| 689 blink::WebContentDecryptionModule* cdm) { | 690 blink::WebContentDecryptionModule* cdm) { |
| 690 DCHECK(main_loop_->BelongsToCurrentThread()); | 691 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 691 | 692 |
| 692 encrypted_media_support_->SetContentDecryptionModule(cdm); | 693 encrypted_media_support_->SetContentDecryptionModule(cdm); |
| 693 } | 694 } |
| 694 | 695 |
| 695 void WebMediaPlayerImpl::setContentDecryptionModule( | 696 void WebMediaPlayerImpl::setContentDecryptionModule( |
| 696 blink::WebContentDecryptionModule* cdm, | 697 blink::WebContentDecryptionModule* cdm, |
| 697 blink::WebContentDecryptionModuleResult result) { | 698 blink::WebContentDecryptionModuleResult result) { |
| 698 DCHECK(main_loop_->BelongsToCurrentThread()); | 699 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 699 | 700 |
| 700 encrypted_media_support_->SetContentDecryptionModule(cdm, result); | 701 encrypted_media_support_->SetContentDecryptionModule(cdm, result); |
| 701 } | 702 } |
| 702 | 703 |
| 703 void WebMediaPlayerImpl::setContentDecryptionModuleSync( | 704 void WebMediaPlayerImpl::setContentDecryptionModuleSync( |
| 704 blink::WebContentDecryptionModule* cdm) { | 705 blink::WebContentDecryptionModule* cdm) { |
| 705 DCHECK(main_loop_->BelongsToCurrentThread()); | 706 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 706 | 707 |
| 707 encrypted_media_support_->SetContentDecryptionModuleSync(cdm); | 708 encrypted_media_support_->SetContentDecryptionModuleSync(cdm); |
| 708 } | 709 } |
| 709 | 710 |
| 710 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, | 711 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, |
| 711 PipelineStatus status) { | 712 PipelineStatus status) { |
| 712 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; | 713 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; |
| 713 DCHECK(main_loop_->BelongsToCurrentThread()); | 714 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 714 seeking_ = false; | 715 seeking_ = false; |
| 715 if (pending_seek_) { | 716 if (pending_seek_) { |
| 716 pending_seek_ = false; | 717 pending_seek_ = false; |
| 717 seek(pending_seek_seconds_); | 718 seek(pending_seek_seconds_); |
| 718 return; | 719 return; |
| 719 } | 720 } |
| 720 | 721 |
| 721 if (status != media::PIPELINE_OK) { | 722 if (status != media::PIPELINE_OK) { |
| 722 OnPipelineError(status); | 723 OnPipelineError(status); |
| 723 return; | 724 return; |
| 724 } | 725 } |
| 725 | 726 |
| 726 // Update our paused time. | 727 // Update our paused time. |
| 727 if (paused_) | 728 if (paused_) |
| 728 paused_time_ = pipeline_.GetMediaTime(); | 729 paused_time_ = pipeline_.GetMediaTime(); |
| 729 | 730 |
| 730 should_notify_time_changed_ = time_changed; | 731 should_notify_time_changed_ = time_changed; |
| 731 } | 732 } |
| 732 | 733 |
| 733 void WebMediaPlayerImpl::OnPipelineEnded() { | 734 void WebMediaPlayerImpl::OnPipelineEnded() { |
| 734 DVLOG(1) << __FUNCTION__; | 735 DVLOG(1) << __FUNCTION__; |
| 735 DCHECK(main_loop_->BelongsToCurrentThread()); | 736 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 736 client_->timeChanged(); | 737 client_->timeChanged(); |
| 737 } | 738 } |
| 738 | 739 |
| 739 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { | 740 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { |
| 740 DCHECK(main_loop_->BelongsToCurrentThread()); | 741 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 741 DCHECK_NE(error, media::PIPELINE_OK); | 742 DCHECK_NE(error, media::PIPELINE_OK); |
| 742 | 743 |
| 743 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { | 744 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { |
| 744 // Any error that occurs before reaching ReadyStateHaveMetadata should | 745 // Any error that occurs before reaching ReadyStateHaveMetadata should |
| 745 // be considered a format error. | 746 // be considered a format error. |
| 746 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 747 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
| 747 return; | 748 return; |
| 748 } | 749 } |
| 749 | 750 |
| 750 SetNetworkState(PipelineErrorToNetworkState(error)); | 751 SetNetworkState(PipelineErrorToNetworkState(error)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 // them and translate them ready state changes http://crbug.com/144683 | 794 // them and translate them ready state changes http://crbug.com/144683 |
| 794 DCHECK_EQ(buffering_state, media::BUFFERING_HAVE_ENOUGH); | 795 DCHECK_EQ(buffering_state, media::BUFFERING_HAVE_ENOUGH); |
| 795 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 796 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
| 796 | 797 |
| 797 // Blink expects a timeChanged() in response to a seek(). | 798 // Blink expects a timeChanged() in response to a seek(). |
| 798 if (should_notify_time_changed_) | 799 if (should_notify_time_changed_) |
| 799 client_->timeChanged(); | 800 client_->timeChanged(); |
| 800 } | 801 } |
| 801 | 802 |
| 802 void WebMediaPlayerImpl::OnDemuxerOpened() { | 803 void WebMediaPlayerImpl::OnDemuxerOpened() { |
| 803 DCHECK(main_loop_->BelongsToCurrentThread()); | 804 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 804 client_->mediaSourceOpened(new WebMediaSourceImpl( | 805 client_->mediaSourceOpened(new WebMediaSourceImpl( |
| 805 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); | 806 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); |
| 806 } | 807 } |
| 807 | 808 |
| 808 void WebMediaPlayerImpl::OnAddTextTrack( | 809 void WebMediaPlayerImpl::OnAddTextTrack( |
| 809 const media::TextTrackConfig& config, | 810 const media::TextTrackConfig& config, |
| 810 const media::AddTextTrackDoneCB& done_cb) { | 811 const media::AddTextTrackDoneCB& done_cb) { |
| 811 DCHECK(main_loop_->BelongsToCurrentThread()); | 812 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 812 | 813 |
| 813 const WebInbandTextTrackImpl::Kind web_kind = | 814 const WebInbandTextTrackImpl::Kind web_kind = |
| 814 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); | 815 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); |
| 815 const blink::WebString web_label = | 816 const blink::WebString web_label = |
| 816 blink::WebString::fromUTF8(config.label()); | 817 blink::WebString::fromUTF8(config.label()); |
| 817 const blink::WebString web_language = | 818 const blink::WebString web_language = |
| 818 blink::WebString::fromUTF8(config.language()); | 819 blink::WebString::fromUTF8(config.language()); |
| 819 const blink::WebString web_id = | 820 const blink::WebString web_id = |
| 820 blink::WebString::fromUTF8(config.id()); | 821 blink::WebString::fromUTF8(config.id()); |
| 821 | 822 |
| 822 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track( | 823 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track( |
| 823 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id, | 824 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id, |
| 824 text_track_index_++)); | 825 text_track_index_++)); |
| 825 | 826 |
| 826 scoped_ptr<media::TextTrack> text_track( | 827 scoped_ptr<media::TextTrack> text_track(new TextTrackImpl( |
| 827 new TextTrackImpl(main_loop_, client_, web_inband_text_track.Pass())); | 828 main_task_runner_, client_, web_inband_text_track.Pass())); |
| 828 | 829 |
| 829 done_cb.Run(text_track.Pass()); | 830 done_cb.Run(text_track.Pass()); |
| 830 } | 831 } |
| 831 | 832 |
| 832 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { | 833 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { |
| 833 DCHECK(main_loop_->BelongsToCurrentThread()); | 834 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 834 | 835 |
| 835 if (!success) { | 836 if (!success) { |
| 836 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 837 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
| 837 return; | 838 return; |
| 838 } | 839 } |
| 839 | 840 |
| 840 StartPipeline(); | 841 StartPipeline(); |
| 841 } | 842 } |
| 842 | 843 |
| 843 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { | 844 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 854 // TODO(xhwang): Move this to a factory class so that we can create different | 855 // TODO(xhwang): Move this to a factory class so that we can create different |
| 855 // renderers. | 856 // renderers. |
| 856 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() { | 857 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() { |
| 857 media::SetDecryptorReadyCB set_decryptor_ready_cb = | 858 media::SetDecryptorReadyCB set_decryptor_ready_cb = |
| 858 encrypted_media_support_->CreateSetDecryptorReadyCB(); | 859 encrypted_media_support_->CreateSetDecryptorReadyCB(); |
| 859 | 860 |
| 860 // Create our audio decoders and renderer. | 861 // Create our audio decoders and renderer. |
| 861 ScopedVector<media::AudioDecoder> audio_decoders; | 862 ScopedVector<media::AudioDecoder> audio_decoders; |
| 862 | 863 |
| 863 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_); | 864 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_); |
| 864 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_, log_cb)); | 865 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_task_runner_, |
| 865 audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_)); | 866 log_cb)); |
| 867 audio_decoders.push_back(new media::OpusAudioDecoder(media_task_runner_)); |
| 866 | 868 |
| 867 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl( | 869 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl( |
| 868 media_loop_, | 870 media_task_runner_, |
| 869 audio_source_provider_.get(), | 871 audio_source_provider_.get(), |
| 870 audio_decoders.Pass(), | 872 audio_decoders.Pass(), |
| 871 set_decryptor_ready_cb, | 873 set_decryptor_ready_cb, |
| 872 RenderThreadImpl::current()->GetAudioHardwareConfig())); | 874 RenderThreadImpl::current()->GetAudioHardwareConfig())); |
| 873 | 875 |
| 874 // Create our video decoders and renderer. | 876 // Create our video decoders and renderer. |
| 875 ScopedVector<media::VideoDecoder> video_decoders; | 877 ScopedVector<media::VideoDecoder> video_decoders; |
| 876 | 878 |
| 877 if (gpu_factories_.get()) { | 879 if (gpu_factories_.get()) { |
| 878 video_decoders.push_back( | 880 video_decoders.push_back( |
| 879 new media::GpuVideoDecoder(gpu_factories_, media_log_)); | 881 new media::GpuVideoDecoder(gpu_factories_, media_log_)); |
| 880 } | 882 } |
| 881 | 883 |
| 882 #if !defined(MEDIA_DISABLE_LIBVPX) | 884 #if !defined(MEDIA_DISABLE_LIBVPX) |
| 883 video_decoders.push_back(new media::VpxVideoDecoder(media_loop_)); | 885 video_decoders.push_back(new media::VpxVideoDecoder(media_task_runner_)); |
| 884 #endif // !defined(MEDIA_DISABLE_LIBVPX) | 886 #endif // !defined(MEDIA_DISABLE_LIBVPX) |
| 885 | 887 |
| 886 video_decoders.push_back(new media::FFmpegVideoDecoder(media_loop_)); | 888 video_decoders.push_back(new media::FFmpegVideoDecoder(media_task_runner_)); |
| 887 | 889 |
| 888 scoped_ptr<media::VideoRenderer> video_renderer( | 890 scoped_ptr<media::VideoRenderer> video_renderer( |
| 889 new media::VideoRendererImpl( | 891 new media::VideoRendererImpl( |
| 890 media_loop_, | 892 media_task_runner_, |
| 891 video_decoders.Pass(), | 893 video_decoders.Pass(), |
| 892 set_decryptor_ready_cb, | 894 set_decryptor_ready_cb, |
| 893 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), | 895 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), |
| 894 true)); | 896 true)); |
| 895 | 897 |
| 896 // Create renderer. | 898 // Create renderer. |
| 897 return scoped_ptr<media::Renderer>(new media::RendererImpl( | 899 return scoped_ptr<media::Renderer>(new media::RendererImpl( |
| 898 media_loop_, | 900 media_task_runner_, |
| 899 demuxer_.get(), | 901 demuxer_.get(), |
| 900 audio_renderer.Pass(), | 902 audio_renderer.Pass(), |
| 901 video_renderer.Pass())); | 903 video_renderer.Pass())); |
| 902 } | 904 } |
| 903 | 905 |
| 904 void WebMediaPlayerImpl::StartPipeline() { | 906 void WebMediaPlayerImpl::StartPipeline() { |
| 905 DCHECK(main_loop_->BelongsToCurrentThread()); | 907 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 906 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 908 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 907 | 909 |
| 908 // Keep track if this is a MSE or non-MSE playback. | 910 // Keep track if this is a MSE or non-MSE playback. |
| 909 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", | 911 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", |
| 910 (load_type_ == LoadTypeMediaSource)); | 912 (load_type_ == LoadTypeMediaSource)); |
| 911 | 913 |
| 912 media::LogCB mse_log_cb; | 914 media::LogCB mse_log_cb; |
| 913 media::Demuxer::NeedKeyCB need_key_cb = | 915 media::Demuxer::NeedKeyCB need_key_cb = |
| 914 encrypted_media_support_->CreateNeedKeyCB(); | 916 encrypted_media_support_->CreateNeedKeyCB(); |
| 915 | 917 |
| 916 // Figure out which demuxer to use. | 918 // Figure out which demuxer to use. |
| 917 if (load_type_ != LoadTypeMediaSource) { | 919 if (load_type_ != LoadTypeMediaSource) { |
| 918 DCHECK(!chunk_demuxer_); | 920 DCHECK(!chunk_demuxer_); |
| 919 DCHECK(data_source_); | 921 DCHECK(data_source_); |
| 920 | 922 |
| 921 demuxer_.reset(new media::FFmpegDemuxer( | 923 demuxer_.reset(new media::FFmpegDemuxer( |
| 922 media_loop_, data_source_.get(), | 924 media_task_runner_, data_source_.get(), |
| 923 need_key_cb, | 925 need_key_cb, |
| 924 media_log_)); | 926 media_log_)); |
| 925 } else { | 927 } else { |
| 926 DCHECK(!chunk_demuxer_); | 928 DCHECK(!chunk_demuxer_); |
| 927 DCHECK(!data_source_); | 929 DCHECK(!data_source_); |
| 928 | 930 |
| 929 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_); | 931 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_); |
| 930 | 932 |
| 931 chunk_demuxer_ = new media::ChunkDemuxer( | 933 chunk_demuxer_ = new media::ChunkDemuxer( |
| 932 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), | 934 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), |
| 933 need_key_cb, | 935 need_key_cb, |
| 934 mse_log_cb, | 936 mse_log_cb, |
| 935 true); | 937 true); |
| 936 demuxer_.reset(chunk_demuxer_); | 938 demuxer_.reset(chunk_demuxer_); |
| 937 } | 939 } |
| 938 | 940 |
| 939 scoped_ptr<media::FilterCollection> filter_collection( | 941 scoped_ptr<media::FilterCollection> filter_collection( |
| 940 new media::FilterCollection()); | 942 new media::FilterCollection()); |
| 941 filter_collection->SetDemuxer(demuxer_.get()); | 943 filter_collection->SetDemuxer(demuxer_.get()); |
| 942 filter_collection->SetRenderer(CreateRenderer()); | 944 filter_collection->SetRenderer(CreateRenderer()); |
| 943 | 945 |
| 944 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { | 946 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { |
| 945 scoped_ptr<media::TextRenderer> text_renderer( | 947 scoped_ptr<media::TextRenderer> text_renderer( |
| 946 new media::TextRenderer( | 948 new media::TextRenderer( |
| 947 media_loop_, | 949 media_task_runner_, |
| 948 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); | 950 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); |
| 949 | 951 |
| 950 filter_collection->SetTextRenderer(text_renderer.Pass()); | 952 filter_collection->SetTextRenderer(text_renderer.Pass()); |
| 951 } | 953 } |
| 952 | 954 |
| 953 // ... and we're ready to go! | 955 // ... and we're ready to go! |
| 954 seeking_ = true; | 956 seeking_ = true; |
| 955 pipeline_.Start( | 957 pipeline_.Start( |
| 956 filter_collection.Pass(), | 958 filter_collection.Pass(), |
| 957 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | 959 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
| 958 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), | 960 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
| 959 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false), | 961 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false), |
| 960 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), | 962 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), |
| 961 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), | 963 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), |
| 962 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged)); | 964 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged)); |
| 963 } | 965 } |
| 964 | 966 |
| 965 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 967 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
| 966 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 968 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
| 967 DCHECK(main_loop_->BelongsToCurrentThread()); | 969 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 968 network_state_ = state; | 970 network_state_ = state; |
| 969 // Always notify to ensure client has the latest value. | 971 // Always notify to ensure client has the latest value. |
| 970 client_->networkStateChanged(); | 972 client_->networkStateChanged(); |
| 971 } | 973 } |
| 972 | 974 |
| 973 void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { | 975 void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { |
| 974 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 976 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
| 975 DCHECK(main_loop_->BelongsToCurrentThread()); | 977 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 976 | 978 |
| 977 if (state == WebMediaPlayer::ReadyStateHaveEnoughData && data_source_ && | 979 if (state == WebMediaPlayer::ReadyStateHaveEnoughData && data_source_ && |
| 978 data_source_->assume_fully_buffered() && | 980 data_source_->assume_fully_buffered() && |
| 979 network_state_ == WebMediaPlayer::NetworkStateLoading) | 981 network_state_ == WebMediaPlayer::NetworkStateLoading) |
| 980 SetNetworkState(WebMediaPlayer::NetworkStateLoaded); | 982 SetNetworkState(WebMediaPlayer::NetworkStateLoaded); |
| 981 | 983 |
| 982 ready_state_ = state; | 984 ready_state_ = state; |
| 983 // Always notify to ensure client has the latest value. | 985 // Always notify to ensure client has the latest value. |
| 984 client_->readyStateChanged(); | 986 client_->readyStateChanged(); |
| 985 } | 987 } |
| 986 | 988 |
| 987 blink::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 989 blink::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |
| 988 return audio_source_provider_.get(); | 990 return audio_source_provider_.get(); |
| 989 } | 991 } |
| 990 | 992 |
| 991 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 993 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
| 992 DCHECK(main_loop_->BelongsToCurrentThread()); | 994 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 993 incremented_externally_allocated_memory_ = true; | 995 incremented_externally_allocated_memory_ = true; |
| 994 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | 996 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 995 kPlayerExtraMemory); | 997 kPlayerExtraMemory); |
| 996 } | 998 } |
| 997 | 999 |
| 998 double WebMediaPlayerImpl::GetPipelineDuration() const { | 1000 double WebMediaPlayerImpl::GetPipelineDuration() const { |
| 999 base::TimeDelta duration = pipeline_.GetMediaDuration(); | 1001 base::TimeDelta duration = pipeline_.GetMediaDuration(); |
| 1000 | 1002 |
| 1001 // Return positive infinity if the resource is unbounded. | 1003 // Return positive infinity if the resource is unbounded. |
| 1002 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration | 1004 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration |
| 1003 if (duration == media::kInfiniteDuration()) | 1005 if (duration == media::kInfiniteDuration()) |
| 1004 return std::numeric_limits<double>::infinity(); | 1006 return std::numeric_limits<double>::infinity(); |
| 1005 | 1007 |
| 1006 return duration.InSecondsF(); | 1008 return duration.InSecondsF(); |
| 1007 } | 1009 } |
| 1008 | 1010 |
| 1009 void WebMediaPlayerImpl::OnDurationChanged() { | 1011 void WebMediaPlayerImpl::OnDurationChanged() { |
| 1010 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 1012 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
| 1011 return; | 1013 return; |
| 1012 | 1014 |
| 1013 client_->durationChanged(); | 1015 client_->durationChanged(); |
| 1014 } | 1016 } |
| 1015 | 1017 |
| 1016 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { | 1018 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
| 1017 DCHECK(main_loop_->BelongsToCurrentThread()); | 1019 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1018 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1020 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1019 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 1021 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
| 1020 | 1022 |
| 1021 media_log_->AddEvent( | 1023 media_log_->AddEvent( |
| 1022 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 1024 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
| 1023 pipeline_metadata_.natural_size = size; | 1025 pipeline_metadata_.natural_size = size; |
| 1024 | 1026 |
| 1025 client_->sizeChanged(); | 1027 client_->sizeChanged(); |
| 1026 } | 1028 } |
| 1027 | 1029 |
| 1028 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { | 1030 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { |
| 1029 DCHECK(main_loop_->BelongsToCurrentThread()); | 1031 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1030 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1032 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1031 | 1033 |
| 1032 opaque_ = opaque; | 1034 opaque_ = opaque; |
| 1033 if (video_weblayer_) | 1035 if (video_weblayer_) |
| 1034 video_weblayer_->setOpaque(opaque_); | 1036 video_weblayer_->setOpaque(opaque_); |
| 1035 } | 1037 } |
| 1036 | 1038 |
| 1037 void WebMediaPlayerImpl::FrameReady( | 1039 void WebMediaPlayerImpl::FrameReady( |
| 1038 const scoped_refptr<media::VideoFrame>& frame) { | 1040 const scoped_refptr<media::VideoFrame>& frame) { |
| 1039 compositor_task_runner_->PostTask( | 1041 compositor_task_runner_->PostTask( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1065 compositor_task_runner_->PostTask(FROM_HERE, | 1067 compositor_task_runner_->PostTask(FROM_HERE, |
| 1066 base::Bind(&GetCurrentFrameAndSignal, | 1068 base::Bind(&GetCurrentFrameAndSignal, |
| 1067 base::Unretained(compositor_), | 1069 base::Unretained(compositor_), |
| 1068 &video_frame, | 1070 &video_frame, |
| 1069 &event)); | 1071 &event)); |
| 1070 event.Wait(); | 1072 event.Wait(); |
| 1071 return video_frame; | 1073 return video_frame; |
| 1072 } | 1074 } |
| 1073 | 1075 |
| 1074 } // namespace content | 1076 } // namespace content |
| OLD | NEW |