OLD | NEW |
---|---|
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 Loading... | |
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 prepareForLoad(); |
philipj_slow
2015/12/18 15:12:24
I think that this bit is made worse by this CL, ex
| |
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 prepareForLoad(); |
505 scheduleDelayedAction(LoadMediaResource); | 507 m_pendingActionFlags |= LoadMediaResource; |
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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
708 | 712 |
709 prepareForLoad(); | 713 prepareForLoad(); |
710 loadInternal(); | 714 loadInternal(); |
711 prepareToPlay(); | 715 prepareToPlay(); |
712 } | 716 } |
713 | 717 |
714 void HTMLMediaElement::prepareForLoad() | 718 void HTMLMediaElement::prepareForLoad() |
715 { | 719 { |
716 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
717 | 721 |
718 // Perform the cleanup required for the resource load algorithm to run. | 722 NetworkState networkState = m_networkState; |
719 stopPeriodicTimers(); | 723 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 | 724 |
731 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 725 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
732 m_loadState = WaitingForSource; | 726 m_loadState = WaitingForSource; |
733 m_currentSourceNode = nullptr; | 727 m_currentSourceNode = nullptr; |
734 | 728 |
735 // 2 - If there are any tasks from the media element's media element event t ask source in | 729 // 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. | 730 // one of the task queues, then remove those tasks. |
737 cancelPendingEventsAndCallbacks(); | 731 cancelPendingEventsAndCallbacks(); |
738 | 732 |
739 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue | 733 // 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. | 734 // a task to fire a simple event named abort at the media element. |
741 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 735 if (networkState == NETWORK_LOADING || networkState == NETWORK_IDLE) |
742 scheduleEvent(EventTypeNames::abort); | 736 scheduleEvent(EventTypeNames::abort); |
743 | 737 |
744 resetMediaPlayerAndMediaSource(); | |
745 | |
746 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps | 738 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps |
747 if (m_networkState != NETWORK_EMPTY) { | 739 if (networkState != NETWORK_EMPTY) { |
748 // 4.1 - Queue a task to fire a simple event named emptied at the media element. | 740 // 4.1 - Queue a task to fire a simple event named emptied at the media element. |
749 scheduleEvent(EventTypeNames::emptied); | 741 scheduleEvent(EventTypeNames::emptied); |
750 | 742 |
751 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. | 743 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. |
752 setNetworkState(NETWORK_EMPTY); | 744 setNetworkState(NETWORK_EMPTY); |
753 | 745 |
754 // 4.3 - Forget the media element's media-resource-specific tracks. | 746 // 4.3 - Forget the media element's media-resource-specific tracks. |
755 forgetResourceSpecificTracks(); | 747 forgetResourceSpecificTracks(); |
756 | 748 |
757 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. | 749 // 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 Loading... | |
2979 audioSourceProvider().setClient(nullptr); | 2971 audioSourceProvider().setClient(nullptr); |
2980 #endif | 2972 #endif |
2981 if (m_webMediaPlayer) { | 2973 if (m_webMediaPlayer) { |
2982 #if ENABLE(WEB_AUDIO) | 2974 #if ENABLE(WEB_AUDIO) |
2983 m_audioSourceProvider.wrap(nullptr); | 2975 m_audioSourceProvider.wrap(nullptr); |
2984 #endif | 2976 #endif |
2985 m_webMediaPlayer.clear(); | 2977 m_webMediaPlayer.clear(); |
2986 } | 2978 } |
2987 } | 2979 } |
2988 | 2980 |
2989 void HTMLMediaElement::clearMediaPlayer(int flags) | 2981 void HTMLMediaElement::resetMediaElement(int flags) |
2990 { | 2982 { |
2991 forgetResourceSpecificTracks(); | 2983 forgetResourceSpecificTracks(); |
2992 | 2984 |
2993 closeMediaSource(); | 2985 closeMediaSource(); |
2994 | 2986 |
2995 cancelDeferredLoad(); | 2987 cancelDeferredLoad(); |
2996 | 2988 |
2997 { | 2989 { |
2998 AudioSourceProviderClientLockScope scope(*this); | 2990 AudioSourceProviderClientLockScope scope(*this); |
2999 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 2991 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
3000 } | 2992 } |
3001 | 2993 |
2994 #if ENABLE(WEB_AUDIO) | |
2995 if (m_audioSourceNode) | |
2996 audioSourceProvider().setClient(m_audioSourceNode); | |
2997 #endif | |
2998 | |
3002 stopPeriodicTimers(); | 2999 stopPeriodicTimers(); |
3003 m_loadTimer.stop(); | 3000 m_loadTimer.stop(); |
3004 | 3001 |
3005 m_pendingActionFlags &= ~flags; | 3002 m_pendingActionFlags &= ~flags; |
3006 m_loadState = WaitingForSource; | 3003 m_loadState = WaitingForSource; |
3007 | 3004 |
3008 // We can't cast if we don't have a media player. | 3005 // We can't cast if we don't have a media player. |
3009 m_remoteRoutesAvailable = false; | 3006 m_remoteRoutesAvailable = false; |
3010 m_playingRemotely = false; | 3007 m_playingRemotely = false; |
3008 | |
3009 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
3010 m_sentEndEvent = false; | |
3011 m_sentStalledEvent = false; | |
3012 m_haveFiredLoadedData = false; | |
3013 m_completelyLoaded = false; | |
3014 m_havePreparedToPlay = false; | |
3015 m_displayMode = Unknown; | |
3016 | |
3017 m_readyState = HAVE_NOTHING; | |
3018 m_readyStateMaximum = HAVE_NOTHING; | |
3019 setNetworkState(NETWORK_EMPTY); | |
3020 setShouldDelayLoadEvent(false); | |
3021 m_currentSourceNode = nullptr; | |
3022 invalidateCachedTime(); | |
3023 cueTimeline().updateActiveCues(0); | |
3024 m_playing = false; | |
3025 m_paused = true; | |
3026 m_seeking = false; | |
3027 | |
3011 if (mediaControls()) | 3028 if (mediaControls()) |
3012 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3029 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
3013 | 3030 |
3014 if (layoutObject()) | 3031 if (layoutObject()) |
3015 layoutObject()->setShouldDoFullPaintInvalidation(); | 3032 layoutObject()->setShouldDoFullPaintInvalidation(); |
3016 } | 3033 } |
3017 | 3034 |
3018 void HTMLMediaElement::stop() | 3035 void HTMLMediaElement::stop() |
3019 { | 3036 { |
3020 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3037 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
3021 | 3038 |
3022 recordMetricsIfPausing(); | 3039 recordMetricsIfPausing(); |
3023 | 3040 |
3024 // Close the async event queue so that no events are enqueued. | 3041 // Close the async event queue so that no events are enqueued. |
3025 cancelPendingEventsAndCallbacks(); | 3042 cancelPendingEventsAndCallbacks(); |
3026 m_asyncEventQueue->close(); | 3043 m_asyncEventQueue->close(); |
3027 | 3044 |
3028 // Stop the playback without generating events | 3045 // Clear everything in the Media Element |
3029 clearMediaPlayer(-1); | 3046 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 | 3047 |
3041 if (layoutObject()) | 3048 if (layoutObject()) |
3042 layoutObject()->updateFromElement(); | 3049 layoutObject()->updateFromElement(); |
3043 | 3050 |
3044 stopPeriodicTimers(); | |
3045 | |
3046 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this | 3051 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this |
3047 // media element will simply leak. | 3052 // media element will simply leak. |
3048 ASSERT(!hasPendingActivity()); | 3053 ASSERT(!hasPendingActivity()); |
3049 } | 3054 } |
3050 | 3055 |
3051 bool HTMLMediaElement::hasPendingActivity() const | 3056 bool HTMLMediaElement::hasPendingActivity() const |
3052 { | 3057 { |
3053 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a | 3058 // 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. | 3059 // resource to load, before networkState has reached to NETWORK_LOADING. |
3055 if (m_shouldDelayLoadEvent) | 3060 if (m_shouldDelayLoadEvent) |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3384 } | 3389 } |
3385 | 3390 |
3386 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3391 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
3387 { | 3392 { |
3388 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3393 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
3389 configureMediaControls(); | 3394 configureMediaControls(); |
3390 | 3395 |
3391 return nullptr; | 3396 return nullptr; |
3392 } | 3397 } |
3393 | 3398 |
3394 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. | 3399 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it. |
3395 void HTMLMediaElement::resetMediaPlayerAndMediaSource() | 3400 void HTMLMediaElement::resetMediaPlayerAndMediaSource() |
3396 { | 3401 { |
3397 closeMediaSource(); | 3402 closeMediaSource(); |
3398 | 3403 |
3399 { | 3404 { |
3400 AudioSourceProviderClientLockScope scope(*this); | 3405 AudioSourceProviderClientLockScope scope(*this); |
3401 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3406 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
3402 } | 3407 } |
3403 | 3408 |
3404 // We haven't yet found out if any remote routes are available. | 3409 // We haven't yet found out if any remote routes are available. |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3632 visitor->trace(m_client); | 3637 visitor->trace(m_client); |
3633 } | 3638 } |
3634 | 3639 |
3635 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3640 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
3636 { | 3641 { |
3637 visitor->trace(m_client); | 3642 visitor->trace(m_client); |
3638 } | 3643 } |
3639 #endif | 3644 #endif |
3640 | 3645 |
3641 } | 3646 } |
OLD | NEW |