Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(662)

Side by Side Diff: media/blink/webmediaplayer_impl.cc

Issue 1762963002: Revert of Extract state management from WebMediaPlayerImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/filters/pipeline_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/blink/webmediaplayer_impl.h" 5 #include "media/blink/webmediaplayer_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/callback.h" 14 #include "base/callback.h"
16 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
17 #include "base/command_line.h" 16 #include "base/command_line.h"
18 #include "base/debug/alias.h" 17 #include "base/debug/alias.h"
19 #include "base/debug/crash_logging.h" 18 #include "base/debug/crash_logging.h"
20 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
21 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
22 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
23 #include "base/task_runner_util.h" 22 #include "base/task_runner_util.h"
24 #include "base/thread_task_runner_handle.h" 23 #include "base/thread_task_runner_handle.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 network_state_(WebMediaPlayer::NetworkStateEmpty), 136 network_state_(WebMediaPlayer::NetworkStateEmpty),
138 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), 137 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
139 preload_(BufferedDataSource::AUTO), 138 preload_(BufferedDataSource::AUTO),
140 buffering_strategy_( 139 buffering_strategy_(
141 BufferedDataSourceInterface::BUFFERING_STRATEGY_NORMAL), 140 BufferedDataSourceInterface::BUFFERING_STRATEGY_NORMAL),
142 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), 141 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
143 media_task_runner_(params.media_task_runner()), 142 media_task_runner_(params.media_task_runner()),
144 worker_task_runner_(params.worker_task_runner()), 143 worker_task_runner_(params.worker_task_runner()),
145 media_log_(params.media_log()), 144 media_log_(params.media_log()),
146 pipeline_(media_task_runner_, media_log_.get()), 145 pipeline_(media_task_runner_, media_log_.get()),
147 pipeline_controller_(
148 &pipeline_,
149 base::Bind(&WebMediaPlayerImpl::CreateRenderer,
150 base::Unretained(this)),
151 base::Bind(&WebMediaPlayerImpl::OnPipelineSeeked, AsWeakPtr()),
152 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()),
153 base::Bind(&WebMediaPlayerImpl::OnPipelineResumed, AsWeakPtr()),
154 base::Bind(&WebMediaPlayerImpl::OnPipelineError, AsWeakPtr())),
155 load_type_(LoadTypeURL), 146 load_type_(LoadTypeURL),
156 opaque_(false), 147 opaque_(false),
157 playback_rate_(0.0), 148 playback_rate_(0.0),
158 paused_(true), 149 paused_(true),
159 seeking_(false), 150 seeking_(false),
151 pending_suspend_(false),
152 pending_time_change_(false),
153 pending_resume_(false),
154 suspending_(false),
155 suspended_(false),
156 resuming_(false),
160 pending_suspend_resume_cycle_(false), 157 pending_suspend_resume_cycle_(false),
161 ended_(false), 158 ended_(false),
159 pending_seek_(false),
160 should_notify_time_changed_(false),
162 fullscreen_(false), 161 fullscreen_(false),
163 decoder_requires_restart_for_fullscreen_(false), 162 decoder_requires_restart_for_fullscreen_(false),
164 client_(client), 163 client_(client),
165 encrypted_client_(encrypted_client), 164 encrypted_client_(encrypted_client),
166 delegate_(delegate), 165 delegate_(delegate),
167 delegate_id_(0), 166 delegate_id_(0),
168 defer_load_cb_(params.defer_load_cb()), 167 defer_load_cb_(params.defer_load_cb()),
169 context_3d_cb_(params.context_3d_cb()), 168 context_3d_cb_(params.context_3d_cb()),
170 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()), 169 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()),
171 last_reported_memory_usage_(0), 170 last_reported_memory_usage_(0),
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 delegate_->PlayerGone(delegate_id_); 223 delegate_->PlayerGone(delegate_id_);
225 delegate_->RemoveObserver(delegate_id_); 224 delegate_->RemoveObserver(delegate_id_);
226 } 225 }
227 226
228 // Abort any pending IO so stopping the pipeline doesn't get blocked. 227 // Abort any pending IO so stopping the pipeline doesn't get blocked.
229 suppress_destruction_errors_ = true; 228 suppress_destruction_errors_ = true;
230 if (data_source_) 229 if (data_source_)
231 data_source_->Abort(); 230 data_source_->Abort();
232 if (chunk_demuxer_) { 231 if (chunk_demuxer_) {
233 chunk_demuxer_->Shutdown(); 232 chunk_demuxer_->Shutdown();
234 chunk_demuxer_ = nullptr; 233 chunk_demuxer_ = NULL;
235 } 234 }
236 235
237 renderer_factory_.reset(); 236 renderer_factory_.reset();
238 237
239 // Make sure to kill the pipeline so there's no more media threads running. 238 // Make sure to kill the pipeline so there's no more media threads running.
240 // Note: stopping the pipeline might block for a long time. 239 // Note: stopping the pipeline might block for a long time.
241 base::WaitableEvent waiter(false, false); 240 base::WaitableEvent waiter(false, false);
242 pipeline_.Stop( 241 pipeline_.Stop(
243 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); 242 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
244 waiter.Wait(); 243 waiter.Wait();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 DCHECK(main_task_runner_->BelongsToCurrentThread()); 335 DCHECK(main_task_runner_->BelongsToCurrentThread());
337 336
338 #if defined(OS_ANDROID) // WMPI_CAST 337 #if defined(OS_ANDROID) // WMPI_CAST
339 if (isRemote()) { 338 if (isRemote()) {
340 cast_impl_.play(); 339 cast_impl_.play();
341 return; 340 return;
342 } 341 }
343 #endif 342 #endif
344 343
345 paused_ = false; 344 paused_ = false;
345
346 pipeline_.SetPlaybackRate(playback_rate_); 346 pipeline_.SetPlaybackRate(playback_rate_);
347
348 if (data_source_) 347 if (data_source_)
349 data_source_->MediaIsPlaying(); 348 data_source_->MediaIsPlaying();
350 349
351 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); 350 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY));
352 351
353 if (playback_rate_ > 0) { 352 if (playback_rate_ > 0) {
353 // Resume the player if playback was initiated in the foreground.
354 if (suspended_ && !resuming_ && delegate_ && !delegate_->IsHidden()) {
355 ScheduleResume();
356 return;
357 }
358
354 NotifyPlaybackStarted(); 359 NotifyPlaybackStarted();
355
356 // Resume the player if playback was initiated in the foreground. Resume()
357 // will do nothing if the pipeline is not suspended state, but will clear
358 // some internal pending state, so it should always be called.
359 if (delegate_ && !delegate_->IsHidden())
360 pipeline_controller_.Resume();
361 } 360 }
362 } 361 }
363 362
364 void WebMediaPlayerImpl::pause() { 363 void WebMediaPlayerImpl::pause() {
365 DVLOG(1) << __FUNCTION__; 364 DVLOG(1) << __FUNCTION__;
366 DCHECK(main_task_runner_->BelongsToCurrentThread()); 365 DCHECK(main_task_runner_->BelongsToCurrentThread());
367 366
368 const bool was_already_paused = paused_ || playback_rate_ == 0; 367 const bool was_already_paused = paused_ || playback_rate_ == 0;
369 paused_ = true; 368 paused_ = true;
370 369
371 #if defined(OS_ANDROID) // WMPI_CAST 370 #if defined(OS_ANDROID) // WMPI_CAST
372 if (isRemote()) { 371 if (isRemote()) {
373 cast_impl_.pause(); 372 cast_impl_.pause();
374 return; 373 return;
375 } 374 }
376 #endif 375 #endif
377 376
378 pipeline_.SetPlaybackRate(0.0); 377 pipeline_.SetPlaybackRate(0.0);
379 378 UpdatePausedTime();
380 // pause() may be called after playback has ended and the HTMLMediaElement
381 // requires that currentTime() == duration() after ending. We want to ensure
382 // |paused_time_| matches currentTime() in this case or a future seek() may
383 // incorrectly discard what it thinks is a seek to the existing time.
384 paused_time_ =
385 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime();
386 379
387 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); 380 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE));
388 381
389 if (!was_already_paused) 382 if (!was_already_paused)
390 NotifyPlaybackPaused(); 383 NotifyPlaybackPaused();
391 } 384 }
392 385
393 bool WebMediaPlayerImpl::supportsSave() const { 386 bool WebMediaPlayerImpl::supportsSave() const {
394 DCHECK(main_task_runner_->BelongsToCurrentThread()); 387 DCHECK(main_task_runner_->BelongsToCurrentThread());
395 return supports_save_; 388 return supports_save_;
396 } 389 }
397 390
398 void WebMediaPlayerImpl::seek(double seconds) { 391 void WebMediaPlayerImpl::seek(double seconds) {
399 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; 392 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)";
400 DCHECK(main_task_runner_->BelongsToCurrentThread()); 393 DCHECK(main_task_runner_->BelongsToCurrentThread());
401 DoSeek(base::TimeDelta::FromSecondsD(seconds), true);
402 }
403
404 void WebMediaPlayerImpl::DoSeek(base::TimeDelta time, bool time_updated) {
405 DCHECK(main_task_runner_->BelongsToCurrentThread());
406 394
407 ended_ = false; 395 ended_ = false;
408 396
397 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds);
398
409 #if defined(OS_ANDROID) // WMPI_CAST 399 #if defined(OS_ANDROID) // WMPI_CAST
410 if (isRemote()) { 400 if (isRemote()) {
411 cast_impl_.seek(time); 401 cast_impl_.seek(new_seek_time);
412 return; 402 return;
413 } 403 }
414 #endif 404 #endif
415 405
416 ReadyState old_state = ready_state_; 406 ReadyState old_state = ready_state_;
417 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) 407 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata)
418 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); 408 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
419 409
420 // When paused, we know exactly what the current time is and can elide seeks 410 if (seeking_ || suspended_) {
421 // to it. However, there are two cases that are not elided: 411 // Once resuming, it's too late to change the resume time and so the
422 // 1) When the pipeline state is not stable. 412 // implementation is a little different.
423 // In this case we just let |pipeline_controller_| decide what to do, as 413 bool is_suspended = suspended_ && !resuming_;
424 // it has complete information. 414
425 // 2) For MSE. 415 // If we are currently seeking or resuming to |new_seek_time|, skip the
426 // Because the buffers may have changed between seeks, MSE seeks are 416 // seek (except for MSE, which always seeks).
427 // never elided. 417 if (!is_suspended && new_seek_time == seek_time_) {
428 if (paused_ && pipeline_controller_.IsStable() && paused_time_ == time && 418 if (chunk_demuxer_) {
429 !chunk_demuxer_) { 419 // Don't suppress any redundant in-progress MSE seek. There could have
430 // If the ready state was high enough before, we can indicate that the seek 420 // been changes to the underlying buffers after seeking the demuxer and
431 // completed just by restoring it. Otherwise we will just wait for the real 421 // before receiving OnPipelineSeeked() for the currently in-progress
432 // ready state change to eventually happen. 422 // seek.
433 if (old_state == ReadyStateHaveEnoughData) { 423 MEDIA_LOG(DEBUG, media_log_)
424 << "Detected MediaSource seek to same time as in-progress seek to "
425 << seek_time_ << ".";
426 } else {
427 // Suppress all redundant seeks if unrestricted by media source demuxer
428 // API.
429 pending_seek_ = false;
430 pending_seek_time_ = base::TimeDelta();
431 return;
432 }
433 }
434
435 // If |chunk_demuxer_| is already seeking, cancel that seek and schedule the
436 // new one.
437 if (!is_suspended && chunk_demuxer_)
438 chunk_demuxer_->CancelPendingSeek(new_seek_time);
439
440 // Schedule a seek once the current suspend or seek finishes.
441 pending_seek_ = true;
442 pending_seek_time_ = new_seek_time;
443
444 // In the case of seeking while suspended, the seek is considered to have
445 // started immediately (but won't complete until the pipeline is resumed).
446 if (is_suspended) {
447 seeking_ = true;
448 seek_time_ = new_seek_time;
449
450 // Resume the pipeline if the seek is initiated in the foreground so that
451 // the correct frame is displayed.
452 if (delegate_ && !delegate_->IsHidden())
453 ScheduleResume();
454 }
455
456 return;
457 }
458
459 media_log_->AddEvent(media_log_->CreateSeekEvent(seconds));
460
461 // Update our paused time.
462 // For non-MSE playbacks, in paused state ignore the seek operations to
463 // current time if the loading is completed and generate
464 // OnPipelineBufferingStateChanged event to eventually fire seeking and seeked
465 // events. We don't short-circuit MSE seeks in this logic because the
466 // underlying buffers around the seek time might have changed (or even been
467 // removed) since previous seek/preroll/pause action, and the pipeline might
468 // need to flush so the new buffers are decoded and rendered instead of the
469 // old ones.
470 if (paused_) {
471 if (paused_time_ != new_seek_time || chunk_demuxer_) {
472 paused_time_ = new_seek_time;
473 } else if (old_state == ReadyStateHaveEnoughData) {
434 main_task_runner_->PostTask( 474 main_task_runner_->PostTask(
435 FROM_HERE, 475 FROM_HERE,
436 base::Bind(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged, 476 base::Bind(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged,
437 AsWeakPtr(), BUFFERING_HAVE_ENOUGH)); 477 AsWeakPtr(), BUFFERING_HAVE_ENOUGH));
478 return;
438 } 479 }
439 return;
440 } 480 }
441 481
442 seeking_ = true; 482 seeking_ = true;
443 seek_time_ = time; 483 seek_time_ = new_seek_time;
444 if (paused_)
445 paused_time_ = time;
446 pipeline_controller_.Seek(time, time_updated);
447 484
448 // Resume the pipeline if the seek is initiated in the foreground so that 485 if (chunk_demuxer_)
449 // the correct frame is displayed. If the pipeline is not suspended, Resume() 486 chunk_demuxer_->StartWaitingForSeek(seek_time_);
450 // will do nothing but clear some pending state. 487
451 if (delegate_ && !delegate_->IsHidden()) 488 pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1(
452 pipeline_controller_.Resume(); 489 &WebMediaPlayerImpl::OnPipelineSeeked, true));
453 } 490 }
454 491
455 void WebMediaPlayerImpl::setRate(double rate) { 492 void WebMediaPlayerImpl::setRate(double rate) {
456 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; 493 DVLOG(1) << __FUNCTION__ << "(" << rate << ")";
457 DCHECK(main_task_runner_->BelongsToCurrentThread()); 494 DCHECK(main_task_runner_->BelongsToCurrentThread());
458 495
459 // TODO(kylep): Remove when support for negatives is added. Also, modify the 496 // TODO(kylep): Remove when support for negatives is added. Also, modify the
460 // following checks so rewind uses reasonable values also. 497 // following checks so rewind uses reasonable values also.
461 if (rate < 0.0) 498 if (rate < 0.0)
462 return; 499 return;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 628
592 double WebMediaPlayerImpl::currentTime() const { 629 double WebMediaPlayerImpl::currentTime() const {
593 DCHECK(main_task_runner_->BelongsToCurrentThread()); 630 DCHECK(main_task_runner_->BelongsToCurrentThread());
594 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); 631 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing);
595 632
596 // TODO(scherkus): Replace with an explicit ended signal to HTMLMediaElement, 633 // TODO(scherkus): Replace with an explicit ended signal to HTMLMediaElement,
597 // see http://crbug.com/409280 634 // see http://crbug.com/409280
598 if (ended_) 635 if (ended_)
599 return duration(); 636 return duration();
600 637
601 if (seeking()) 638 // We know the current seek time better than pipeline: pipeline may processing
602 return seek_time_.InSecondsF(); 639 // an earlier seek before a pending seek has been started, or it might not yet
640 // have the current seek time returnable via GetMediaTime().
641 if (seeking()) {
642 return pending_seek_ ? pending_seek_time_.InSecondsF()
643 : seek_time_.InSecondsF();
644 }
603 645
604 #if defined(OS_ANDROID) // WMPI_CAST 646 #if defined(OS_ANDROID) // WMPI_CAST
605 if (isRemote()) 647 if (isRemote()) {
606 return cast_impl_.currentTime(); 648 return cast_impl_.currentTime();
649 }
607 #endif 650 #endif
608 651
609 if (paused_) 652 if (paused_) {
610 return paused_time_.InSecondsF(); 653 return paused_time_.InSecondsF();
654 }
611 655
612 return pipeline_.GetMediaTime().InSecondsF(); 656 return pipeline_.GetMediaTime().InSecondsF();
613 } 657 }
614 658
615 WebMediaPlayer::NetworkState WebMediaPlayerImpl::getNetworkState() const { 659 WebMediaPlayer::NetworkState WebMediaPlayerImpl::getNetworkState() const {
616 DCHECK(main_task_runner_->BelongsToCurrentThread()); 660 DCHECK(main_task_runner_->BelongsToCurrentThread());
617 return network_state_; 661 return network_state_;
618 } 662 }
619 663
620 WebMediaPlayer::ReadyState WebMediaPlayerImpl::getReadyState() const { 664 WebMediaPlayer::ReadyState WebMediaPlayerImpl::getReadyState() const {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 is_cdm_attached_ = true; 877 is_cdm_attached_ = true;
834 return; 878 return;
835 } 879 }
836 880
837 set_cdm_result_->completeWithError( 881 set_cdm_result_->completeWithError(
838 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0, 882 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0,
839 "Unable to set MediaKeys object"); 883 "Unable to set MediaKeys object");
840 set_cdm_result_.reset(); 884 set_cdm_result_.reset();
841 } 885 }
842 886
843 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) { 887 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed,
888 PipelineStatus status) {
889 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")";
890 DCHECK(main_task_runner_->BelongsToCurrentThread());
891
892 if (status != PIPELINE_OK) {
893 OnPipelineError(status);
894 return;
895 }
896
897 // Whether or not the seek was caused by a resume, we're not suspended now.
898 const bool was_resuming = resuming_;
899 resuming_ = false;
900 suspended_ = false;
901
902 // If we we're resuming into the playing state, notify the delegate.
903 if (was_resuming && playback_rate_ > 0 && !paused_)
904 NotifyPlaybackStarted();
905
906 // If there is a pending suspend, the seek does not complete until after the
907 // next resume.
908 if (pending_suspend_) {
909 pending_suspend_ = false;
910 pending_time_change_ = time_changed;
911 Suspend();
912 return;
913 }
914
915 // Clear seek state. Note that if the seek was caused by a resume, then
916 // |seek_time_| is always set but |seeking_| is only set if there was a
917 // pending seek at the time.
844 seeking_ = false; 918 seeking_ = false;
845 seek_time_ = base::TimeDelta(); 919 seek_time_ = base::TimeDelta();
920
921 if (pending_seek_) {
922 double pending_seek_seconds = pending_seek_time_.InSecondsF();
923 pending_seek_ = false;
924 pending_seek_time_ = base::TimeDelta();
925 seek(pending_seek_seconds);
926 return;
927 }
928
929 // Update our paused time.
846 if (paused_) 930 if (paused_)
847 paused_time_ = pipeline_.GetMediaTime(); 931 UpdatePausedTime();
848 if (time_updated) 932
849 should_notify_time_changed_ = true; 933 should_notify_time_changed_ = time_changed;
850 } 934 }
851 935
852 void WebMediaPlayerImpl::OnPipelineSuspended() { 936 void WebMediaPlayerImpl::OnPipelineSuspended(PipelineStatus status) {
937 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
938 DCHECK(main_task_runner_->BelongsToCurrentThread());
939
940 if (status != PIPELINE_OK) {
941 OnPipelineError(status);
942 return;
943 }
944
945 suspending_ = false;
946 if (delegate_)
947 delegate_->PlayerGone(delegate_id_);
948
853 #if defined(OS_ANDROID) 949 #if defined(OS_ANDROID)
854 if (isRemote()) { 950 if (isRemote()) {
855 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); 951 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner();
856 if (frame) { 952 if (frame) {
857 compositor_->PaintFrameUsingOldRenderingPath(frame); 953 compositor_->PaintFrameUsingOldRenderingPath(frame);
858 } 954 }
859 } 955 }
860 #endif 956 #endif
861 957
862 if (delegate_) 958 if (pending_resume_ || pending_suspend_resume_cycle_) {
863 delegate_->PlayerGone(delegate_id_); 959 pending_resume_ = false;
864
865 if (pending_suspend_resume_cycle_) {
866 pending_suspend_resume_cycle_ = false; 960 pending_suspend_resume_cycle_ = false;
867 pipeline_controller_.Resume(); 961 Resume();
868 return; 962 return;
869 } 963 }
870 } 964 }
871 965
872 void WebMediaPlayerImpl::OnPipelineResumed() {
873 if (playback_rate_ > 0 && !paused_)
874 NotifyPlaybackStarted();
875 }
876
877 void WebMediaPlayerImpl::OnPipelineEnded() { 966 void WebMediaPlayerImpl::OnPipelineEnded() {
878 DVLOG(1) << __FUNCTION__; 967 DVLOG(1) << __FUNCTION__;
879 DCHECK(main_task_runner_->BelongsToCurrentThread()); 968 DCHECK(main_task_runner_->BelongsToCurrentThread());
880 969
881 // Ignore state changes until we've completed all outstanding operations. 970 // Ignore state changes until we've completed all outstanding seeks.
882 if (!pipeline_controller_.IsStable()) 971 if (seeking_ || pending_seek_)
883 return; 972 return;
884 973
885 ended_ = true; 974 ended_ = true;
886 client_->timeChanged(); 975 client_->timeChanged();
887 } 976 }
888 977
889 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { 978 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) {
890 DVLOG(1) << __FUNCTION__; 979 DVLOG(1) << __FUNCTION__;
891 DCHECK(main_task_runner_->BelongsToCurrentThread()); 980 DCHECK(main_task_runner_->BelongsToCurrentThread());
892 DCHECK_NE(error, PIPELINE_OK); 981 DCHECK_NE(error, PIPELINE_OK);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 // playback. 1025 // playback.
937 if (delegate_ && delegate_->IsHidden()) 1026 if (delegate_ && delegate_->IsHidden())
938 OnHidden(false); 1027 OnHidden(false);
939 } 1028 }
940 } 1029 }
941 1030
942 void WebMediaPlayerImpl::OnPipelineBufferingStateChanged( 1031 void WebMediaPlayerImpl::OnPipelineBufferingStateChanged(
943 BufferingState buffering_state) { 1032 BufferingState buffering_state) {
944 DVLOG(1) << __FUNCTION__ << "(" << buffering_state << ")"; 1033 DVLOG(1) << __FUNCTION__ << "(" << buffering_state << ")";
945 1034
946 // Ignore buffering state changes until we've completed all outstanding 1035 // Ignore buffering state changes until we've completed all outstanding seeks.
947 // operations. 1036 if (seeking_ || pending_seek_)
948 if (!pipeline_controller_.IsStable())
949 return; 1037 return;
950 1038
951 // TODO(scherkus): Handle other buffering states when Pipeline starts using 1039 // TODO(scherkus): Handle other buffering states when Pipeline starts using
952 // them and translate them ready state changes http://crbug.com/144683 1040 // them and translate them ready state changes http://crbug.com/144683
953 DCHECK_EQ(buffering_state, BUFFERING_HAVE_ENOUGH); 1041 DCHECK_EQ(buffering_state, BUFFERING_HAVE_ENOUGH);
954 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 1042 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
955 1043
956 // Let the DataSource know we have enough data. It may use this information to 1044 // Let the DataSource know we have enough data. It may use this information to
957 // release unused network connections. 1045 // release unused network connections.
958 if (data_source_) 1046 if (data_source_)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 return; 1100 return;
1013 } 1101 }
1014 1102
1015 #if defined(OS_ANDROID) 1103 #if defined(OS_ANDROID)
1016 // If we're remote, the pipeline should already be suspended. 1104 // If we're remote, the pipeline should already be suspended.
1017 if (isRemote()) 1105 if (isRemote())
1018 return; 1106 return;
1019 #endif 1107 #endif
1020 1108
1021 if (must_suspend || (paused_ && ended_) || hasVideo()) 1109 if (must_suspend || (paused_ && ended_) || hasVideo())
1022 pipeline_controller_.Suspend(); 1110 ScheduleSuspend();
1111 }
1112
1113 void WebMediaPlayerImpl::ScheduleSuspend() {
1114 if (!pipeline_.IsRunning())
1115 return;
1116
1117 if (resuming_ || seeking_) {
1118 pending_suspend_ = true;
1119 return;
1120 }
1121
1122 if (pending_resume_) {
1123 pending_resume_ = false;
1124 return;
1125 }
1126
1127 Suspend();
1128 }
1129
1130 void WebMediaPlayerImpl::Suspend() {
1131 DCHECK(main_task_runner_->BelongsToCurrentThread());
1132
1133 // Since Pipeline::IsRunning() may be set on the media thread there are cases
1134 // where two suspends might be issued concurrently.
1135 if (suspended_)
1136 return;
1137
1138 suspended_ = true;
1139 suspending_ = true;
1140 pipeline_.Suspend(
1141 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSuspended));
1023 } 1142 }
1024 1143
1025 void WebMediaPlayerImpl::OnShown() { 1144 void WebMediaPlayerImpl::OnShown() {
1026 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1145 DCHECK(main_task_runner_->BelongsToCurrentThread());
1027 1146
1028 #if !defined(OS_ANDROID) 1147 #if !defined(OS_ANDROID)
1029 // Suspend/Resume is enabled by default on Android. 1148 // Suspend/Resume is enabled by default on Android.
1030 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( 1149 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1031 switches::kEnableMediaSuspend)) { 1150 switches::kEnableMediaSuspend)) {
1032 return; 1151 return;
1033 } 1152 }
1034 #endif // !defined(OS_ANDROID) 1153 #endif // !defined(OS_ANDROID)
1035 1154
1036 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 1155 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1037 switches::kDisableMediaSuspend)) { 1156 switches::kDisableMediaSuspend)) {
1038 return; 1157 return;
1039 } 1158 }
1040 1159
1041 #if defined(OS_ANDROID) 1160 #if defined(OS_ANDROID)
1042 // If we're remote, the pipeline should stay suspended. 1161 // If we're remote, the pipeline should stay suspended.
1043 if (isRemote()) 1162 if (isRemote())
1044 return; 1163 return;
1045 #endif 1164 #endif
1046 1165
1047 if (!ended_ && !paused_) 1166 if (!ended_ && !paused_)
1048 pipeline_controller_.Resume(); 1167 ScheduleResume();
1168 }
1169
1170 void WebMediaPlayerImpl::ScheduleResume() {
1171 if (!pipeline_.IsRunning())
1172 return;
1173
1174 if (suspending_) {
1175 pending_resume_ = true;
1176 return;
1177 }
1178
1179 if (pending_suspend_) {
1180 pending_suspend_ = false;
1181 return;
1182 }
1183
1184 // Might already be resuming iff we came back from remote playback recently.
1185 if (suspended_ && !resuming_)
1186 Resume();
1049 } 1187 }
1050 1188
1051 void WebMediaPlayerImpl::OnPlay() { 1189 void WebMediaPlayerImpl::OnPlay() {
1052 play(); 1190 play();
1053 client_->playbackStateChanged(); 1191 client_->playbackStateChanged();
1054 } 1192 }
1055 1193
1056 void WebMediaPlayerImpl::OnPause() { 1194 void WebMediaPlayerImpl::OnPause() {
1057 pause(); 1195 pause();
1058 client_->playbackStateChanged(); 1196 client_->playbackStateChanged();
1059 } 1197 }
1060 1198
1061 void WebMediaPlayerImpl::OnVolumeMultiplierUpdate(double multiplier) { 1199 void WebMediaPlayerImpl::OnVolumeMultiplierUpdate(double multiplier) {
1062 volume_multiplier_ = multiplier; 1200 volume_multiplier_ = multiplier;
1063 setVolume(volume_); 1201 setVolume(volume_);
1064 } 1202 }
1065 1203
1204 void WebMediaPlayerImpl::Resume() {
1205 DCHECK(main_task_runner_->BelongsToCurrentThread());
1206 CHECK(suspended_);
1207 CHECK(!resuming_);
1208
1209 // If there was a time change pending when we suspended (which can happen when
1210 // we suspend immediately after a seek), surface it after resuming.
1211 bool time_changed = pending_time_change_;
1212 pending_time_change_ = false;
1213
1214 if (seeking_ || pending_seek_) {
1215 if (pending_seek_) {
1216 seek_time_ = pending_seek_time_;
1217 pending_seek_ = false;
1218 pending_seek_time_ = base::TimeDelta();
1219 }
1220 time_changed = true;
1221 } else {
1222 // It is safe to call GetCurrentFrameTimestamp() because VFC is stopped
1223 // during Suspend(). It won't be started again until after Resume() is
1224 // called. Use the pipeline time if there's no video.
1225 if (!data_source_ || !data_source_->IsStreaming()) {
1226 seek_time_ = hasVideo() ? compositor_->GetCurrentFrameTimestamp()
1227 : pipeline_.GetMediaTime();
1228 } else {
1229 // Resume from zero if a resource does not support range requests; this
1230 // avoids a painful "read-the-whole-file" seek penalty.
1231 seek_time_ = base::TimeDelta();
1232 }
1233 }
1234
1235 if (chunk_demuxer_)
1236 chunk_demuxer_->StartWaitingForSeek(seek_time_);
1237
1238 resuming_ = true;
1239 pipeline_.Resume(CreateRenderer(), seek_time_,
1240 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked,
1241 time_changed));
1242 }
1243
1066 void WebMediaPlayerImpl::ScheduleRestart() { 1244 void WebMediaPlayerImpl::ScheduleRestart() {
1067 if (!pipeline_controller_.IsSuspended()) { 1245 // If we're suspended but not resuming there is no need to restart because
1246 // there is no renderer to kill.
1247 if (!suspended_ || resuming_) {
1068 pending_suspend_resume_cycle_ = true; 1248 pending_suspend_resume_cycle_ = true;
1069 pipeline_controller_.Suspend(); 1249 ScheduleSuspend();
1070 } 1250 }
1071 } 1251 }
1072 1252
1073 #if defined(OS_ANDROID) // WMPI_CAST 1253 #if defined(OS_ANDROID) // WMPI_CAST
1254
1074 bool WebMediaPlayerImpl::isRemote() const { 1255 bool WebMediaPlayerImpl::isRemote() const {
1075 return cast_impl_.isRemote(); 1256 return cast_impl_.isRemote();
1076 } 1257 }
1077 1258
1078 void WebMediaPlayerImpl::SetMediaPlayerManager( 1259 void WebMediaPlayerImpl::SetMediaPlayerManager(
1079 RendererMediaPlayerManagerInterface* media_player_manager) { 1260 RendererMediaPlayerManagerInterface* media_player_manager) {
1080 cast_impl_.SetMediaPlayerManager(media_player_manager); 1261 cast_impl_.SetMediaPlayerManager(media_player_manager);
1081 } 1262 }
1082 1263
1083 void WebMediaPlayerImpl::requestRemotePlayback() { 1264 void WebMediaPlayerImpl::requestRemotePlayback() {
1084 cast_impl_.requestRemotePlayback(); 1265 cast_impl_.requestRemotePlayback();
1085 } 1266 }
1086 1267
1087 void WebMediaPlayerImpl::requestRemotePlaybackControl() { 1268 void WebMediaPlayerImpl::requestRemotePlaybackControl() {
1088 cast_impl_.requestRemotePlaybackControl(); 1269 cast_impl_.requestRemotePlaybackControl();
1089 } 1270 }
1090 1271
1091 void WebMediaPlayerImpl::OnRemotePlaybackEnded() { 1272 void WebMediaPlayerImpl::OnRemotePlaybackEnded() {
1092 DVLOG(1) << __FUNCTION__; 1273 DVLOG(1) << __FUNCTION__;
1093 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1274 DCHECK(main_task_runner_->BelongsToCurrentThread());
1094 1275
1095 ended_ = true; 1276 ended_ = true;
1096 client_->timeChanged(); 1277 client_->timeChanged();
1097 } 1278 }
1098 1279
1099 void WebMediaPlayerImpl::OnDisconnectedFromRemoteDevice(double t) { 1280 void WebMediaPlayerImpl::OnDisconnectedFromRemoteDevice(double t) {
1100 DoSeek(base::TimeDelta::FromSecondsD(t), false); 1281 paused_time_ = base::TimeDelta::FromSecondsD(t);
1101 if (delegate_ && !delegate_->IsHidden()) 1282 pending_seek_ = true;
1102 pipeline_controller_.Resume(); 1283 pending_seek_time_ = paused_time_;
1103 1284
1285 ScheduleResume();
1286
1287 if (paused_time_ == pipeline_.GetMediaDuration()) {
1288 ended_ = true;
1289 }
1104 // We already told the delegate we're paused when remoting started. 1290 // We already told the delegate we're paused when remoting started.
1105 client_->playbackStateChanged(); 1291 client_->playbackStateChanged();
1106 client_->disconnectedFromRemoteDevice(); 1292 client_->disconnectedFromRemoteDevice();
1107 } 1293 }
1108 1294
1109 void WebMediaPlayerImpl::SuspendForRemote() { 1295 void WebMediaPlayerImpl::SuspendForRemote() {
1110 if (!pipeline_controller_.IsSuspended()) { 1296 if (suspended_ && !suspending_) {
1111 pipeline_controller_.Suspend();
1112 } else {
1113 // TODO(sandersd): If PipelineController::Suspend() called |suspended_cb|
1114 // when already suspended, we wouldn't need this case.
1115 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); 1297 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner();
1116 if (frame) { 1298 if (frame) {
1117 compositor_->PaintFrameUsingOldRenderingPath(frame); 1299 compositor_->PaintFrameUsingOldRenderingPath(frame);
1118 } 1300 }
1119 } 1301 }
1302 ScheduleSuspend();
1120 } 1303 }
1121 1304
1122 gfx::Size WebMediaPlayerImpl::GetCanvasSize() const { 1305 gfx::Size WebMediaPlayerImpl::GetCanvasSize() const {
1123 if (!video_weblayer_) 1306 if (!video_weblayer_)
1124 return pipeline_metadata_.natural_size; 1307 return pipeline_metadata_.natural_size;
1125 1308
1126 return video_weblayer_->bounds(); 1309 return video_weblayer_->bounds();
1127 } 1310 }
1128 1311
1129 void WebMediaPlayerImpl::SetDeviceScaleFactor(float scale_factor) { 1312 void WebMediaPlayerImpl::SetDeviceScaleFactor(float scale_factor) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 chunk_demuxer_ = new ChunkDemuxer( 1403 chunk_demuxer_ = new ChunkDemuxer(
1221 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), 1404 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened),
1222 encrypted_media_init_data_cb, media_log_, true); 1405 encrypted_media_init_data_cb, media_log_, true);
1223 demuxer_.reset(chunk_demuxer_); 1406 demuxer_.reset(chunk_demuxer_);
1224 } 1407 }
1225 1408
1226 // ... and we're ready to go! 1409 // ... and we're ready to go!
1227 seeking_ = true; 1410 seeking_ = true;
1228 1411
1229 // TODO(sandersd): On Android, defer Start() if the tab is not visible. 1412 // TODO(sandersd): On Android, defer Start() if the tab is not visible.
1230 bool is_streaming = (data_source_ && data_source_->IsStreaming()); 1413 pipeline_.Start(
1231 pipeline_controller_.Start( 1414 demuxer_.get(), CreateRenderer(),
1232 chunk_demuxer_, demuxer_.get(), is_streaming,
1233 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), 1415 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
1416 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
1417 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false),
1234 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), 1418 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata),
1235 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), 1419 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged),
1236 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged), 1420 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged),
1237 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack), 1421 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack),
1238 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey)); 1422 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey));
1239 } 1423 }
1240 1424
1241 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { 1425 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) {
1242 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; 1426 DVLOG(1) << __FUNCTION__ << "(" << state << ")";
1243 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1427 DCHECK(main_task_runner_->BelongsToCurrentThread());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 base::WaitableEvent event(false, false); 1515 base::WaitableEvent event(false, false);
1332 compositor_task_runner_->PostTask(FROM_HERE, 1516 compositor_task_runner_->PostTask(FROM_HERE,
1333 base::Bind(&GetCurrentFrameAndSignal, 1517 base::Bind(&GetCurrentFrameAndSignal,
1334 base::Unretained(compositor_), 1518 base::Unretained(compositor_),
1335 &video_frame, 1519 &video_frame,
1336 &event)); 1520 &event));
1337 event.Wait(); 1521 event.Wait();
1338 return video_frame; 1522 return video_frame;
1339 } 1523 }
1340 1524
1525 void WebMediaPlayerImpl::UpdatePausedTime() {
1526 DCHECK(main_task_runner_->BelongsToCurrentThread());
1527
1528 // pause() may be called after playback has ended and the HTMLMediaElement
1529 // requires that currentTime() == duration() after ending. We want to ensure
1530 // |paused_time_| matches currentTime() in this case or a future seek() may
1531 // incorrectly discard what it thinks is a seek to the existing time.
1532 paused_time_ =
1533 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime();
1534 }
1535
1341 void WebMediaPlayerImpl::NotifyPlaybackStarted() { 1536 void WebMediaPlayerImpl::NotifyPlaybackStarted() {
1342 #if defined(OS_ANDROID) // WMPI_CAST 1537 #if defined(OS_ANDROID) // WMPI_CAST
1343 // We do not tell our delegates about remote playback, because that would 1538 // We do not tell our delegates about remote playback, because that would
1344 // keep the device awake, which is not what we want. 1539 // keep the device awake, which is not what we want.
1345 if (isRemote()) 1540 if (isRemote())
1346 return; 1541 return;
1347 #endif 1542 #endif
1348 1543
1349 // NotifyPlaybackStarted() may be called by interactions while suspended, 1544 // Don't send delegate notifications when suspended; upon suspend we send
1350 // (play/pause in particular). Those actions won't have any effect until the 1545 // PlayerGone() to the delegate -- no more notifications should be sent until
1351 // pipeline is resumed. 1546 // after resume.
1352 // TODO(dalecurtis): Should these be dropped at the call sites instead? 1547 if (suspended_)
1353 // Alternatively, rename this method to include Maybe or Changed, and handle
1354 // multiple calls safely.
1355 if (pipeline_controller_.IsSuspended())
1356 return; 1548 return;
1357 1549
1358 if (delegate_) { 1550 if (delegate_) {
1359 delegate_->DidPlay(delegate_id_, hasVideo(), hasAudio(), false, 1551 delegate_->DidPlay(delegate_id_, hasVideo(), hasAudio(), false,
1360 pipeline_.GetMediaDuration()); 1552 pipeline_.GetMediaDuration());
1361 } 1553 }
1362 if (!memory_usage_reporting_timer_.IsRunning()) { 1554 if (!memory_usage_reporting_timer_.IsRunning()) {
1363 memory_usage_reporting_timer_.Start(FROM_HERE, 1555 memory_usage_reporting_timer_.Start(FROM_HERE,
1364 base::TimeDelta::FromSeconds(2), this, 1556 base::TimeDelta::FromSeconds(2), this,
1365 &WebMediaPlayerImpl::ReportMemoryUsage); 1557 &WebMediaPlayerImpl::ReportMemoryUsage);
1366 } 1558 }
1367 } 1559 }
1368 1560
1369 void WebMediaPlayerImpl::NotifyPlaybackPaused() { 1561 void WebMediaPlayerImpl::NotifyPlaybackPaused() {
1370 #if defined(OS_ANDROID) // WMPI_CAST 1562 #if defined(OS_ANDROID) // WMPI_CAST
1371 if (isRemote()) 1563 if (isRemote())
1372 return; 1564 return;
1373 #endif 1565 #endif
1374 1566 // Don't send delegate notifications when suspended; upon suspend we send
1375 // Same as above, NotifyPlaybackPaused() may be called by interactions while 1567 // PlayerGone() to the delegate -- no more notifications should be sent until
1376 // suspended, but those actions won't have any effect until the pipeline is 1568 // after resume.
1377 // resumed. 1569 if (!suspended_ && delegate_)
1378 if (pipeline_controller_.IsSuspended())
1379 return;
1380
1381 if (delegate_)
1382 delegate_->DidPause(delegate_id_, ended_); 1570 delegate_->DidPause(delegate_id_, ended_);
1383 memory_usage_reporting_timer_.Stop(); 1571 memory_usage_reporting_timer_.Stop();
1384 ReportMemoryUsage(); 1572 ReportMemoryUsage();
1385 } 1573 }
1386 1574
1387 void WebMediaPlayerImpl::ReportMemoryUsage() { 1575 void WebMediaPlayerImpl::ReportMemoryUsage() {
1388 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1576 DCHECK(main_task_runner_->BelongsToCurrentThread());
1389 1577
1390 // About base::Unretained() usage below: We destroy |demuxer_| on the main 1578 // About base::Unretained() usage below: We destroy |demuxer_| on the main
1391 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the 1579 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the
(...skipping 23 matching lines...) Expand all
1415 << ", Video: " << stats.video_memory_usage << ", DataSource: " 1603 << ", Video: " << stats.video_memory_usage << ", DataSource: "
1416 << (data_source_ ? data_source_->GetMemoryUsage() : 0) 1604 << (data_source_ ? data_source_->GetMemoryUsage() : 0)
1417 << ", Demuxer: " << demuxer_memory_usage; 1605 << ", Demuxer: " << demuxer_memory_usage;
1418 1606
1419 const int64_t delta = current_memory_usage - last_reported_memory_usage_; 1607 const int64_t delta = current_memory_usage - last_reported_memory_usage_;
1420 last_reported_memory_usage_ = current_memory_usage; 1608 last_reported_memory_usage_ = current_memory_usage;
1421 adjust_allocated_memory_cb_.Run(delta); 1609 adjust_allocated_memory_cb_.Run(delta);
1422 } 1610 }
1423 1611
1424 } // namespace media 1612 } // namespace media
OLDNEW
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/filters/pipeline_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698