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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 1522463003: Refactor resource load and resource selection algorithms as per spec (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update per spec as per review comments Created 5 years 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 | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 464
465 removeElementFromDocumentMap(this, &oldDocument); 465 removeElementFromDocumentMap(this, &oldDocument);
466 addElementToDocumentMap(this, &document()); 466 addElementToDocumentMap(this, &document());
467 467
468 // FIXME: This is a temporary fix to prevent this object from causing the 468 // FIXME: This is a temporary fix to prevent this object from causing the
469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the 469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the
470 // previous document. This restarts the load, as if the src attribute had be en set. 470 // previous document. This restarts the load, as if the src attribute had be en set.
471 // A proper fix would provide a mechanism to allow this object to refresh 471 // A proper fix would provide a mechanism to allow this object to refresh
472 // the MediaPlayer's LocalFrame and FrameLoader references on 472 // the MediaPlayer's LocalFrame and FrameLoader references on
473 // document changes so that playback can be resumed properly. 473 // document changes so that playback can be resumed properly.
474 clearMediaPlayer(LoadMediaResource); 474 invokeLoadAlgorith();
475 scheduleDelayedAction(LoadMediaResource); 475 m_pendingActionFlags |= LoadMediaResource;
476 if (!m_loadTimer.isActive())
477 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
476 478
477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed 479 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed
478 // and there is no risk of dispatching a load event from within the destruct or. 480 // and there is no risk of dispatching a load event from within the destruct or.
479 oldDocument.decrementLoadEventDelayCount(); 481 oldDocument.decrementLoadEventDelayCount();
480 482
481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); 483 ActiveDOMObject::didMoveToNewExecutionContext(&document());
482 HTMLElement::didMoveToNewDocument(oldDocument); 484 HTMLElement::didMoveToNewDocument(oldDocument);
483 } 485 }
484 486
485 bool HTMLMediaElement::supportsFocus() const 487 bool HTMLMediaElement::supportsFocus() const
486 { 488 {
487 if (ownerDocument()->isMediaDocument()) 489 if (ownerDocument()->isMediaDocument())
488 return false; 490 return false;
489 491
490 // If no controls specified, we should still be able to focus the element if it has tabIndex. 492 // If no controls specified, we should still be able to focus the element if it has tabIndex.
491 return shouldShowControls() || HTMLElement::supportsFocus(); 493 return shouldShowControls() || HTMLElement::supportsFocus();
492 } 494 }
493 495
494 bool HTMLMediaElement::isMouseFocusable() const 496 bool HTMLMediaElement::isMouseFocusable() const
495 { 497 {
496 return false; 498 return false;
497 } 499 }
498 500
499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) 501 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value)
500 { 502 {
501 if (name == srcAttr) { 503 if (name == srcAttr) {
502 // Trigger a reload, as long as the 'src' attribute is present. 504 // Trigger a reload, as long as the 'src' attribute is present.
503 if (!value.isNull()) { 505 if (!value.isNull()) {
504 clearMediaPlayer(LoadMediaResource); 506 invokeLoadAlgorith();
505 scheduleDelayedAction(LoadMediaResource); 507 m_pendingActionFlags |= LoadMediaResource;
Srirama 2015/12/16 07:33:43 May be we can move this as well inside, probably w
philipj_slow 2015/12/16 15:51:07 Yes, unless all of this could be moved inside the
508 if (!m_loadTimer.isActive())
509 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
506 } 510 }
507 } else if (name == controlsAttr) { 511 } else if (name == controlsAttr) {
508 configureMediaControls(); 512 configureMediaControls();
509 } else if (name == preloadAttr) { 513 } else if (name == preloadAttr) {
510 setPlayerPreload(); 514 setPlayerPreload();
511 } else { 515 } else {
512 HTMLElement::parseAttribute(name, oldValue, value); 516 HTMLElement::parseAttribute(name, oldValue, value);
513 } 517 }
514 } 518 }
515 519
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 { 577 {
574 if (layoutObject()) 578 if (layoutObject())
575 layoutObject()->updateFromElement(); 579 layoutObject()->updateFromElement();
576 } 580 }
577 581
578 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) 582 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType)
579 { 583 {
580 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); 584 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this);
581 585
582 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) { 586 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) {
583 prepareForLoad(); 587 invokeLoadAlgorith();
584 m_pendingActionFlags |= LoadMediaResource; 588 m_pendingActionFlags |= LoadMediaResource;
585 } 589 }
586 590
587 if (actionType & LoadTextTrackResource) 591 if (actionType & LoadTextTrackResource)
588 m_pendingActionFlags |= LoadTextTrackResource; 592 m_pendingActionFlags |= LoadTextTrackResource;
589 593
590 if (!m_loadTimer.isActive()) 594 if (!m_loadTimer.isActive())
591 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); 595 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
592 } 596 }
593 597
594 void HTMLMediaElement::scheduleNextSourceChild() 598 void HTMLMediaElement::scheduleNextSourceChild()
595 { 599 {
596 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. 600 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala invokeLoadAlgorith.
597 m_pendingActionFlags |= LoadMediaResource; 601 m_pendingActionFlags |= LoadMediaResource;
598 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); 602 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
599 } 603 }
600 604
601 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) 605 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
602 { 606 {
603 scheduleEvent(Event::createCancelable(eventName)); 607 scheduleEvent(Event::createCancelable(eventName));
604 } 608 }
605 609
606 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) 610 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event)
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 703
700 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { 704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) {
701 recordAutoplayMetric(AutoplayEnabledThroughLoad); 705 recordAutoplayMetric(AutoplayEnabledThroughLoad);
702 m_userGestureRequiredForPlay = false; 706 m_userGestureRequiredForPlay = false;
703 // While usergesture-initiated load()s technically count as autoplayed, 707 // While usergesture-initiated load()s technically count as autoplayed,
704 // they don't feel like such to the users and hence we don't want to 708 // they don't feel like such to the users and hence we don't want to
705 // count them for the purposes of metrics. 709 // count them for the purposes of metrics.
706 m_autoplayMediaCounted = true; 710 m_autoplayMediaCounted = true;
707 } 711 }
708 712
709 prepareForLoad(); 713 invokeLoadAlgorith();
philipj_slow 2015/12/16 15:51:07 In fact, I would keep the name prepareForLoad() fo
710 loadInternal(); 714 loadInternal();
711 prepareToPlay(); 715 prepareToPlay();
712 } 716 }
713 717
714 void HTMLMediaElement::prepareForLoad() 718 // 4.8.13.5 Loading the media resource
719 void HTMLMediaElement::invokeLoadAlgorith()
715 { 720 {
716 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); 721 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorith(%p)", this);
717 722
718 // Perform the cleanup required for the resource load algorithm to run. 723 NetworkState networkState = m_networkState;
719 stopPeriodicTimers(); 724 resetMediaElement(LoadMediaResource);
720 m_loadTimer.stop();
721 cancelDeferredLoad();
722 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
723 m_pendingActionFlags &= ~LoadMediaResource;
724 m_sentEndEvent = false;
725 m_sentStalledEvent = false;
726 m_haveFiredLoadedData = false;
727 m_completelyLoaded = false;
728 m_havePreparedToPlay = false;
729 m_displayMode = Unknown;
730 725
731 // 1 - Abort any already-running instance of the resource selection algorith m for this element. 726 // 1 - Abort any already-running instance of the resource selection algorith m for this element.
732 m_loadState = WaitingForSource; 727 m_loadState = WaitingForSource;
733 m_currentSourceNode = nullptr; 728 m_currentSourceNode = nullptr;
734 729
735 // 2 - If there are any tasks from the media element's media element event t ask source in 730 // 2 - If there are any tasks from the media element's media element event t ask source in
736 // one of the task queues, then remove those tasks. 731 // one of the task queues, then remove those tasks.
737 cancelPendingEventsAndCallbacks(); 732 cancelPendingEventsAndCallbacks();
738 733
739 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue 734 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue
740 // a task to fire a simple event named abort at the media element. 735 // a task to fire a simple event named abort at the media element.
741 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) 736 if (networkState == NETWORK_LOADING || networkState == NETWORK_IDLE)
742 scheduleEvent(EventTypeNames::abort); 737 scheduleEvent(EventTypeNames::abort);
743 738
744 resetMediaPlayerAndMediaSource();
745
746 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 739 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
747 if (m_networkState != NETWORK_EMPTY) { 740 if (networkState != NETWORK_EMPTY) {
Srirama 2015/12/16 07:33:43 Most of this section is covered in resetMediaEleme
748 // 4.1 - Queue a task to fire a simple event named emptied at the media element. 741 // 4.1 - Queue a task to fire a simple event named emptied at the media element.
749 scheduleEvent(EventTypeNames::emptied); 742 scheduleEvent(EventTypeNames::emptied);
750 743
751 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. 744 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
752 setNetworkState(NETWORK_EMPTY); 745 setNetworkState(NETWORK_EMPTY);
753 746
754 // 4.3 - Forget the media element's media-resource-specific tracks. 747 // 4.3 - Forget the media element's media-resource-specific tracks.
755 forgetResourceSpecificTracks(); 748 forgetResourceSpecificTracks();
756 749
757 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. 750 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate.
(...skipping 2221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 audioSourceProvider().setClient(nullptr); 2972 audioSourceProvider().setClient(nullptr);
2980 #endif 2973 #endif
2981 if (m_webMediaPlayer) { 2974 if (m_webMediaPlayer) {
2982 #if ENABLE(WEB_AUDIO) 2975 #if ENABLE(WEB_AUDIO)
2983 m_audioSourceProvider.wrap(nullptr); 2976 m_audioSourceProvider.wrap(nullptr);
2984 #endif 2977 #endif
2985 m_webMediaPlayer.clear(); 2978 m_webMediaPlayer.clear();
2986 } 2979 }
2987 } 2980 }
2988 2981
2989 void HTMLMediaElement::clearMediaPlayer(int flags) 2982 void HTMLMediaElement::resetMediaElement(int flags)
2990 { 2983 {
2991 forgetResourceSpecificTracks(); 2984 forgetResourceSpecificTracks();
2992 2985
2993 closeMediaSource(); 2986 closeMediaSource();
2994 2987
2995 cancelDeferredLoad(); 2988 cancelDeferredLoad();
2996 2989
2997 { 2990 {
2998 AudioSourceProviderClientLockScope scope(*this); 2991 AudioSourceProviderClientLockScope scope(*this);
2999 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 2992 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3000 } 2993 }
3001 2994
2995 #if ENABLE(WEB_AUDIO)
2996 if (m_audioSourceNode)
2997 audioSourceProvider().setClient(m_audioSourceNode);
2998 #endif
2999
3002 stopPeriodicTimers(); 3000 stopPeriodicTimers();
3003 m_loadTimer.stop(); 3001 m_loadTimer.stop();
3004 3002
3005 m_pendingActionFlags &= ~flags; 3003 m_pendingActionFlags &= ~flags;
3006 m_loadState = WaitingForSource; 3004 m_loadState = WaitingForSource;
3007 3005
3008 // We can't cast if we don't have a media player. 3006 // We can't cast if we don't have a media player.
3009 m_remoteRoutesAvailable = false; 3007 m_remoteRoutesAvailable = false;
3010 m_playingRemotely = false; 3008 m_playingRemotely = false;
3009
3010 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
3011 m_sentEndEvent = false;
3012 m_sentStalledEvent = false;
3013 m_haveFiredLoadedData = false;
3014 m_completelyLoaded = false;
3015 m_havePreparedToPlay = false;
3016 m_displayMode = Unknown;
3017
3018 m_readyState = HAVE_NOTHING;
3019 m_readyStateMaximum = HAVE_NOTHING;
3020 setNetworkState(NETWORK_EMPTY);
3021 setShouldDelayLoadEvent(false);
3022 m_currentSourceNode = nullptr;
3023 invalidateCachedTime();
3024 cueTimeline().updateActiveCues(0);
3025 m_playing = false;
3026 m_paused = true;
3027 m_seeking = false;
3028
3011 if (mediaControls()) 3029 if (mediaControls())
3012 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); 3030 mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
3013 3031
3014 if (layoutObject()) 3032 if (layoutObject())
3015 layoutObject()->setShouldDoFullPaintInvalidation(); 3033 layoutObject()->setShouldDoFullPaintInvalidation();
3016 } 3034 }
3017 3035
3018 void HTMLMediaElement::stop() 3036 void HTMLMediaElement::stop()
3019 { 3037 {
3020 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); 3038 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this);
3021 3039
3022 recordMetricsIfPausing(); 3040 recordMetricsIfPausing();
3023 3041
3024 // Close the async event queue so that no events are enqueued. 3042 // Close the async event queue so that no events are enqueued.
3025 cancelPendingEventsAndCallbacks(); 3043 cancelPendingEventsAndCallbacks();
3026 m_asyncEventQueue->close(); 3044 m_asyncEventQueue->close();
3027 3045
3028 // Stop the playback without generating events 3046 // Clear everything in the Media Element
3029 clearMediaPlayer(-1); 3047 resetMediaElement(-1);
3030 m_readyState = HAVE_NOTHING;
3031 m_readyStateMaximum = HAVE_NOTHING;
3032 setNetworkState(NETWORK_EMPTY);
3033 setShouldDelayLoadEvent(false);
3034 m_currentSourceNode = nullptr;
3035 invalidateCachedTime();
3036 cueTimeline().updateActiveCues(0);
3037 m_playing = false;
3038 m_paused = true;
3039 m_seeking = false;
3040 3048
3041 if (layoutObject()) 3049 if (layoutObject())
3042 layoutObject()->updateFromElement(); 3050 layoutObject()->updateFromElement();
3043 3051
3044 stopPeriodicTimers();
3045
3046 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this 3052 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this
3047 // media element will simply leak. 3053 // media element will simply leak.
3048 ASSERT(!hasPendingActivity()); 3054 ASSERT(!hasPendingActivity());
3049 } 3055 }
3050 3056
3051 bool HTMLMediaElement::hasPendingActivity() const 3057 bool HTMLMediaElement::hasPendingActivity() const
3052 { 3058 {
3053 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a 3059 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a
3054 // resource to load, before networkState has reached to NETWORK_LOADING. 3060 // resource to load, before networkState has reached to NETWORK_LOADING.
3055 if (m_shouldDelayLoadEvent) 3061 if (m_shouldDelayLoadEvent)
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 } 3390 }
3385 3391
3386 void* HTMLMediaElement::preDispatchEventHandler(Event* event) 3392 void* HTMLMediaElement::preDispatchEventHandler(Event* event)
3387 { 3393 {
3388 if (event && event->type() == EventTypeNames::webkitfullscreenchange) 3394 if (event && event->type() == EventTypeNames::webkitfullscreenchange)
3389 configureMediaControls(); 3395 configureMediaControls();
3390 3396
3391 return nullptr; 3397 return nullptr;
3392 } 3398 }
3393 3399
3394 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. 3400 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it.
3395 void HTMLMediaElement::resetMediaPlayerAndMediaSource() 3401 void HTMLMediaElement::resetMediaPlayerAndMediaSource()
3396 { 3402 {
3397 closeMediaSource(); 3403 closeMediaSource();
3398 3404
3399 { 3405 {
3400 AudioSourceProviderClientLockScope scope(*this); 3406 AudioSourceProviderClientLockScope scope(*this);
3401 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 3407 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3402 } 3408 }
3403 3409
3404 // We haven't yet found out if any remote routes are available. 3410 // We haven't yet found out if any remote routes are available.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3632 visitor->trace(m_client); 3638 visitor->trace(m_client);
3633 } 3639 }
3634 3640
3635 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) 3641 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl)
3636 { 3642 {
3637 visitor->trace(m_client); 3643 visitor->trace(m_client);
3638 } 3644 }
3639 #endif 3645 #endif
3640 3646
3641 } 3647 }
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698