| 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 |
| 3 * reserved. |
| 3 * | 4 * |
| 4 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 6 * are met: | 7 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
| 12 * | 13 * |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 #include "wtf/MathExtras.h" | 95 #include "wtf/MathExtras.h" |
| 95 #include "wtf/PtrUtil.h" | 96 #include "wtf/PtrUtil.h" |
| 96 #include "wtf/text/CString.h" | 97 #include "wtf/text/CString.h" |
| 97 #include <limits> | 98 #include <limits> |
| 98 | 99 |
| 99 #ifndef BLINK_MEDIA_LOG | 100 #ifndef BLINK_MEDIA_LOG |
| 100 #define BLINK_MEDIA_LOG DVLOG(3) | 101 #define BLINK_MEDIA_LOG DVLOG(3) |
| 101 #endif | 102 #endif |
| 102 | 103 |
| 103 #ifndef LOG_MEDIA_EVENTS | 104 #ifndef LOG_MEDIA_EVENTS |
| 104 // Default to not logging events because so many are generated they can overwhel
m the rest of | 105 // Default to not logging events because so many are generated they can |
| 105 // the logging. | 106 // overwhelm the rest of the logging. |
| 106 #define LOG_MEDIA_EVENTS 0 | 107 #define LOG_MEDIA_EVENTS 0 |
| 107 #endif | 108 #endif |
| 108 | 109 |
| 109 #ifndef LOG_CACHED_TIME_WARNINGS | 110 #ifndef LOG_CACHED_TIME_WARNINGS |
| 110 // Default to not logging warnings about excessive drift in the cached media tim
e because it adds a | 111 // Default to not logging warnings about excessive drift in the cached media |
| 111 // fair amount of overhead and logging. | 112 // time because it adds a fair amount of overhead and logging. |
| 112 #define LOG_CACHED_TIME_WARNINGS 0 | 113 #define LOG_CACHED_TIME_WARNINGS 0 |
| 113 #endif | 114 #endif |
| 114 | 115 |
| 115 namespace blink { | 116 namespace blink { |
| 116 | 117 |
| 117 using namespace HTMLNames; | 118 using namespace HTMLNames; |
| 118 | 119 |
| 119 using WeakMediaElementSet = HeapHashSet<WeakMember<HTMLMediaElement>>; | 120 using WeakMediaElementSet = HeapHashSet<WeakMember<HTMLMediaElement>>; |
| 120 using DocumentElementSetMap = | 121 using DocumentElementSetMap = |
| 121 HeapHashMap<WeakMember<Document>, Member<WeakMediaElementSet>>; | 122 HeapHashMap<WeakMember<Document>, Member<WeakMediaElementSet>>; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 NOTREACHED(); | 235 NOTREACHED(); |
| 235 return emptyAtom; | 236 return emptyAtom; |
| 236 } | 237 } |
| 237 | 238 |
| 238 bool canLoadURL(const KURL& url, const ContentType& contentType) { | 239 bool canLoadURL(const KURL& url, const ContentType& contentType) { |
| 239 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 240 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| 240 | 241 |
| 241 String contentMIMEType = contentType.type().lower(); | 242 String contentMIMEType = contentType.type().lower(); |
| 242 String contentTypeCodecs = contentType.parameter(codecs); | 243 String contentTypeCodecs = contentType.parameter(codecs); |
| 243 | 244 |
| 244 // If the MIME type is missing or is not meaningful, try to figure it out from
the URL. | 245 // If the MIME type is missing or is not meaningful, try to figure it out from |
| 246 // the URL. |
| 245 if (contentMIMEType.isEmpty() || | 247 if (contentMIMEType.isEmpty() || |
| 246 contentMIMEType == "application/octet-stream" || | 248 contentMIMEType == "application/octet-stream" || |
| 247 contentMIMEType == "text/plain") { | 249 contentMIMEType == "text/plain") { |
| 248 if (url.protocolIsData()) | 250 if (url.protocolIsData()) |
| 249 contentMIMEType = mimeTypeFromDataURL(url.getString()); | 251 contentMIMEType = mimeTypeFromDataURL(url.getString()); |
| 250 } | 252 } |
| 251 | 253 |
| 252 // If no MIME type is specified, always attempt to load. | 254 // If no MIME type is specified, always attempt to load. |
| 253 if (contentMIMEType.isEmpty()) | 255 if (contentMIMEType.isEmpty()) |
| 254 return true; | 256 return true; |
| 255 | 257 |
| 256 // 4.8.10.3 MIME types - In the absence of a specification to the contrary, th
e MIME type "application/octet-stream" | 258 // 4.8.10.3 MIME types - In the absence of a specification to the contrary, |
| 257 // when used with parameters, e.g. "application/octet-stream;codecs=theora", i
s a type that the user agent knows | 259 // the MIME type "application/octet-stream" when used with parameters, e.g. |
| 258 // it cannot render. | 260 // "application/octet-stream;codecs=theora", is a type that the user agent |
| 261 // knows it cannot render. |
| 259 if (contentMIMEType != "application/octet-stream" || | 262 if (contentMIMEType != "application/octet-stream" || |
| 260 contentTypeCodecs.isEmpty()) { | 263 contentTypeCodecs.isEmpty()) { |
| 261 WebMimeRegistry::SupportsType supported = | 264 WebMimeRegistry::SupportsType supported = |
| 262 Platform::current()->mimeRegistry()->supportsMediaMIMEType( | 265 Platform::current()->mimeRegistry()->supportsMediaMIMEType( |
| 263 contentMIMEType, contentTypeCodecs); | 266 contentMIMEType, contentTypeCodecs); |
| 264 return supported > WebMimeRegistry::IsNotSupported; | 267 return supported > WebMimeRegistry::IsNotSupported; |
| 265 } | 268 } |
| 266 | 269 |
| 267 return false; | 270 return false; |
| 268 } | 271 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 361 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| 359 | 362 |
| 360 String type = contentType.type().lower(); | 363 String type = contentType.type().lower(); |
| 361 // The codecs string is not lower-cased because MP4 values are case sensitive | 364 // The codecs string is not lower-cased because MP4 values are case sensitive |
| 362 // per http://tools.ietf.org/html/rfc4281#page-7. | 365 // per http://tools.ietf.org/html/rfc4281#page-7. |
| 363 String typeCodecs = contentType.parameter(codecs); | 366 String typeCodecs = contentType.parameter(codecs); |
| 364 | 367 |
| 365 if (type.isEmpty()) | 368 if (type.isEmpty()) |
| 366 return WebMimeRegistry::IsNotSupported; | 369 return WebMimeRegistry::IsNotSupported; |
| 367 | 370 |
| 368 // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty st
ring if type is a type that the | 371 // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty |
| 369 // user agent knows it cannot render or is the type "application/octet-stream" | 372 // string if type is a type that the user agent knows it cannot render or is |
| 373 // the type "application/octet-stream" |
| 370 if (type == "application/octet-stream") | 374 if (type == "application/octet-stream") |
| 371 return WebMimeRegistry::IsNotSupported; | 375 return WebMimeRegistry::IsNotSupported; |
| 372 | 376 |
| 373 return Platform::current()->mimeRegistry()->supportsMediaMIMEType(type, | 377 return Platform::current()->mimeRegistry()->supportsMediaMIMEType(type, |
| 374 typeCodecs); | 378 typeCodecs); |
| 375 } | 379 } |
| 376 | 380 |
| 377 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0; | 381 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0; |
| 378 | 382 |
| 379 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) { | 383 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 bool newDocumentRequiresUserGesture = | 508 bool newDocumentRequiresUserGesture = |
| 505 (document().settings() && | 509 (document().settings() && |
| 506 document().settings()->mediaPlaybackRequiresUserGesture()) || | 510 document().settings()->mediaPlaybackRequiresUserGesture()) || |
| 507 m_autoplayHelper->isExperimentEnabled(); | 511 m_autoplayHelper->isExperimentEnabled(); |
| 508 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) { | 512 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) { |
| 509 m_lockedPendingUserGesture = true; | 513 m_lockedPendingUserGesture = true; |
| 510 } | 514 } |
| 511 | 515 |
| 512 if (m_shouldDelayLoadEvent) { | 516 if (m_shouldDelayLoadEvent) { |
| 513 document().incrementLoadEventDelayCount(); | 517 document().incrementLoadEventDelayCount(); |
| 514 // Note: Keeping the load event delay count increment on oldDocument that wa
s added | 518 // Note: Keeping the load event delay count increment on oldDocument that |
| 515 // when m_shouldDelayLoadEvent was set so that destruction of m_webMediaPlay
er can not | 519 // was added when m_shouldDelayLoadEvent was set so that destruction of |
| 516 // cause load event dispatching in oldDocument. | 520 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
| 517 } else { | 521 } else { |
| 518 // Incrementing the load event delay count so that destruction of m_webMedia
Player can not | 522 // Incrementing the load event delay count so that destruction of |
| 519 // cause load event dispatching in oldDocument. | 523 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
| 520 oldDocument.incrementLoadEventDelayCount(); | 524 oldDocument.incrementLoadEventDelayCount(); |
| 521 } | 525 } |
| 522 | 526 |
| 523 removeElementFromDocumentMap(this, &oldDocument); | 527 removeElementFromDocumentMap(this, &oldDocument); |
| 524 addElementToDocumentMap(this, &document()); | 528 addElementToDocumentMap(this, &document()); |
| 525 | 529 |
| 526 // FIXME: This is a temporary fix to prevent this object from causing the | 530 // FIXME: This is a temporary fix to prevent this object from causing the |
| 527 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 531 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
| 528 // previous document. This restarts the load, as if the src attribute had been
set. | 532 // previous document. This restarts the load, as if the src attribute had been |
| 529 // A proper fix would provide a mechanism to allow this object to refresh | 533 // set. A proper fix would provide a mechanism to allow this object to |
| 530 // the MediaPlayer's LocalFrame and FrameLoader references on | 534 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document |
| 531 // document changes so that playback can be resumed properly. | 535 // changes so that playback can be resumed properly. |
| 532 m_ignorePreloadNone = false; | 536 m_ignorePreloadNone = false; |
| 533 invokeLoadAlgorithm(); | 537 invokeLoadAlgorithm(); |
| 534 | 538 |
| 535 // Decrement the load event delay count on oldDocument now that m_webMediaPlay
er has been destroyed | 539 // Decrement the load event delay count on oldDocument now that |
| 536 // and there is no risk of dispatching a load event from within the destructor
. | 540 // m_webMediaPlayer has been destroyed and there is no risk of dispatching a |
| 541 // load event from within the destructor. |
| 537 oldDocument.decrementLoadEventDelayCount(); | 542 oldDocument.decrementLoadEventDelayCount(); |
| 538 | 543 |
| 539 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 544 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
| 540 HTMLElement::didMoveToNewDocument(oldDocument); | 545 HTMLElement::didMoveToNewDocument(oldDocument); |
| 541 } | 546 } |
| 542 | 547 |
| 543 bool HTMLMediaElement::supportsFocus() const { | 548 bool HTMLMediaElement::supportsFocus() const { |
| 544 if (ownerDocument()->isMediaDocument()) | 549 if (ownerDocument()->isMediaDocument()) |
| 545 return false; | 550 return false; |
| 546 | 551 |
| 547 // If no controls specified, we should still be able to focus the element if i
t has tabIndex. | 552 // If no controls specified, we should still be able to focus the element if |
| 553 // it has tabIndex. |
| 548 return shouldShowControls() || HTMLElement::supportsFocus(); | 554 return shouldShowControls() || HTMLElement::supportsFocus(); |
| 549 } | 555 } |
| 550 | 556 |
| 551 bool HTMLMediaElement::isMouseFocusable() const { | 557 bool HTMLMediaElement::isMouseFocusable() const { |
| 552 return false; | 558 return false; |
| 553 } | 559 } |
| 554 | 560 |
| 555 void HTMLMediaElement::parseAttribute(const QualifiedName& name, | 561 void HTMLMediaElement::parseAttribute(const QualifiedName& name, |
| 556 const AtomicString& oldValue, | 562 const AtomicString& oldValue, |
| 557 const AtomicString& value) { | 563 const AtomicString& value) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 void HTMLMediaElement::scheduleTextTrackResourceLoad() { | 647 void HTMLMediaElement::scheduleTextTrackResourceLoad() { |
| 642 BLINK_MEDIA_LOG << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; | 648 BLINK_MEDIA_LOG << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; |
| 643 | 649 |
| 644 m_pendingActionFlags |= LoadTextTrackResource; | 650 m_pendingActionFlags |= LoadTextTrackResource; |
| 645 | 651 |
| 646 if (!m_loadTimer.isActive()) | 652 if (!m_loadTimer.isActive()) |
| 647 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 653 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 648 } | 654 } |
| 649 | 655 |
| 650 void HTMLMediaElement::scheduleNextSourceChild() { | 656 void HTMLMediaElement::scheduleNextSourceChild() { |
| 651 // Schedule the timer to try the next <source> element WITHOUT resetting state
ala invokeLoadAlgorithm. | 657 // Schedule the timer to try the next <source> element WITHOUT resetting state |
| 658 // ala invokeLoadAlgorithm. |
| 652 m_pendingActionFlags |= LoadMediaResource; | 659 m_pendingActionFlags |= LoadMediaResource; |
| 653 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 660 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 654 } | 661 } |
| 655 | 662 |
| 656 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) { | 663 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) { |
| 657 scheduleEvent(Event::createCancelable(eventName)); | 664 scheduleEvent(Event::createCancelable(eventName)); |
| 658 } | 665 } |
| 659 | 666 |
| 660 void HTMLMediaElement::scheduleEvent(Event* event) { | 667 void HTMLMediaElement::scheduleEvent(Event* event) { |
| 661 #if LOG_MEDIA_EVENTS | 668 #if LOG_MEDIA_EVENTS |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 740 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
| 734 // once microtask is implemented for "Await a stable state" step | 741 // once microtask is implemented for "Await a stable state" step |
| 735 // in resource selection algorithm. | 742 // in resource selection algorithm. |
| 736 void HTMLMediaElement::invokeLoadAlgorithm() { | 743 void HTMLMediaElement::invokeLoadAlgorithm() { |
| 737 BLINK_MEDIA_LOG << "invokeLoadAlgorithm(" << (void*)this << ")"; | 744 BLINK_MEDIA_LOG << "invokeLoadAlgorithm(" << (void*)this << ")"; |
| 738 | 745 |
| 739 // Perform the cleanup required for the resource load algorithm to run. | 746 // Perform the cleanup required for the resource load algorithm to run. |
| 740 stopPeriodicTimers(); | 747 stopPeriodicTimers(); |
| 741 m_loadTimer.stop(); | 748 m_loadTimer.stop(); |
| 742 cancelDeferredLoad(); | 749 cancelDeferredLoad(); |
| 743 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if neces
sary and set m_pendingActionFlags to 0 here. | 750 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if |
| 751 // necessary and set m_pendingActionFlags to 0 here. |
| 744 m_pendingActionFlags &= ~LoadMediaResource; | 752 m_pendingActionFlags &= ~LoadMediaResource; |
| 745 m_sentStalledEvent = false; | 753 m_sentStalledEvent = false; |
| 746 m_haveFiredLoadedData = false; | 754 m_haveFiredLoadedData = false; |
| 747 m_displayMode = Unknown; | 755 m_displayMode = Unknown; |
| 748 | 756 |
| 749 // 1 - Abort any already-running instance of the resource selection algorithm
for this element. | 757 // 1 - Abort any already-running instance of the resource selection algorithm |
| 758 // for this element. |
| 750 m_loadState = WaitingForSource; | 759 m_loadState = WaitingForSource; |
| 751 m_currentSourceNode = nullptr; | 760 m_currentSourceNode = nullptr; |
| 752 | 761 |
| 753 // 2 - Let pending tasks be a list of tasks from the media element's media | 762 // 2 - Let pending tasks be a list of tasks from the media element's media |
| 754 // element task source in one of the task queues. | 763 // element task source in one of the task queues. |
| 755 // | 764 // |
| 756 // 3 - For each task in the pending tasks that would run resolve pending | 765 // 3 - For each task in the pending tasks that would run resolve pending |
| 757 // play promises or project pending play prmoises algorithms, immediately | 766 // play promises or project pending play prmoises algorithms, immediately |
| 758 // resolve or reject those promises in the order the corresponding tasks | 767 // resolve or reject those promises in the order the corresponding tasks |
| 759 // were queued. | 768 // were queued. |
| 760 // | 769 // |
| 761 // TODO(mlamouri): the promises are first resolved then rejected but the | 770 // TODO(mlamouri): the promises are first resolved then rejected but the |
| 762 // order between resolved/rejected promises isn't respected. This could be | 771 // order between resolved/rejected promises isn't respected. This could be |
| 763 // improved when the same task is used for both cases. | 772 // improved when the same task is used for both cases. |
| 764 if (m_playPromiseResolveTask->isPending()) { | 773 if (m_playPromiseResolveTask->isPending()) { |
| 765 m_playPromiseResolveTask->cancel(); | 774 m_playPromiseResolveTask->cancel(); |
| 766 resolveScheduledPlayPromises(); | 775 resolveScheduledPlayPromises(); |
| 767 } | 776 } |
| 768 if (m_playPromiseRejectTask->isPending()) { | 777 if (m_playPromiseRejectTask->isPending()) { |
| 769 m_playPromiseRejectTask->cancel(); | 778 m_playPromiseRejectTask->cancel(); |
| 770 rejectScheduledPlayPromises(); | 779 rejectScheduledPlayPromises(); |
| 771 } | 780 } |
| 772 | 781 |
| 773 // 4 - Remove each task in pending tasks from its task queue. | 782 // 4 - Remove each task in pending tasks from its task queue. |
| 774 cancelPendingEventsAndCallbacks(); | 783 cancelPendingEventsAndCallbacks(); |
| 775 | 784 |
| 776 // 5 - If the media element's networkState is set to NETWORK_LOADING or NETWOR
K_IDLE, queue | 785 // 5 - If the media element's networkState is set to NETWORK_LOADING or |
| 777 // a task to fire a simple event named abort at the media element. | 786 // NETWORK_IDLE, queue a task to fire a simple event named abort at the media |
| 787 // element. |
| 778 if (m_networkState == kNetworkLoading || m_networkState == kNetworkIdle) | 788 if (m_networkState == kNetworkLoading || m_networkState == kNetworkIdle) |
| 779 scheduleEvent(EventTypeNames::abort); | 789 scheduleEvent(EventTypeNames::abort); |
| 780 | 790 |
| 781 resetMediaPlayerAndMediaSource(); | 791 resetMediaPlayerAndMediaSource(); |
| 782 | 792 |
| 783 // 6 - If the media element's networkState is not set to NETWORK_EMPTY, then r
un these substeps | 793 // 6 - If the media element's networkState is not set to NETWORK_EMPTY, then |
| 794 // run these substeps |
| 784 if (m_networkState != kNetworkEmpty) { | 795 if (m_networkState != kNetworkEmpty) { |
| 785 // 4.1 - Queue a task to fire a simple event named emptied at the media elem
ent. | 796 // 4.1 - Queue a task to fire a simple event named emptied at the media |
| 797 // element. |
| 786 scheduleEvent(EventTypeNames::emptied); | 798 scheduleEvent(EventTypeNames::emptied); |
| 787 | 799 |
| 788 // 4.2 - If a fetching process is in progress for the media element, the use
r agent should stop it. | 800 // 4.2 - If a fetching process is in progress for the media element, the |
| 801 // user agent should stop it. |
| 789 setNetworkState(kNetworkEmpty); | 802 setNetworkState(kNetworkEmpty); |
| 790 | 803 |
| 791 // 4.4 - Forget the media element's media-resource-specific tracks. | 804 // 4.4 - Forget the media element's media-resource-specific tracks. |
| 792 forgetResourceSpecificTracks(); | 805 forgetResourceSpecificTracks(); |
| 793 | 806 |
| 794 // 4.5 - If readyState is not set to kHaveNothing, then set it to that state
. | 807 // 4.5 - If readyState is not set to kHaveNothing, then set it to that |
| 808 // state. |
| 795 m_readyState = kHaveNothing; | 809 m_readyState = kHaveNothing; |
| 796 m_readyStateMaximum = kHaveNothing; | 810 m_readyStateMaximum = kHaveNothing; |
| 797 | 811 |
| 798 DCHECK(!m_paused || m_playPromiseResolvers.isEmpty()); | 812 DCHECK(!m_paused || m_playPromiseResolvers.isEmpty()); |
| 799 | 813 |
| 800 // 4.6 - If the paused attribute is false, then run these substeps | 814 // 4.6 - If the paused attribute is false, then run these substeps |
| 801 if (!m_paused) { | 815 if (!m_paused) { |
| 802 // 4.6.1 - Set the paused attribute to true. | 816 // 4.6.1 - Set the paused attribute to true. |
| 803 m_paused = true; | 817 m_paused = true; |
| 804 | 818 |
| 805 // 4.6.2 - Take pending play promises and reject pending play promises wit
h the result and an "AbortError" DOMException. | 819 // 4.6.2 - Take pending play promises and reject pending play promises |
| 820 // with the result and an "AbortError" DOMException. |
| 806 rejectPlayPromises( | 821 rejectPlayPromises( |
| 807 AbortError, | 822 AbortError, |
| 808 "The play() request was interrupted by a new load request."); | 823 "The play() request was interrupted by a new load request."); |
| 809 } | 824 } |
| 810 | 825 |
| 811 // 4.7 - If seeking is true, set it to false. | 826 // 4.7 - If seeking is true, set it to false. |
| 812 m_seeking = false; | 827 m_seeking = false; |
| 813 | 828 |
| 814 // 4.8 - Set the current playback position to 0. | 829 // 4.8 - Set the current playback position to 0. |
| 815 // Set the official playback position to 0. | 830 // Set the official playback position to 0. |
| 816 // If this changed the official playback position, then queue a task t
o fire a simple event named timeupdate at the media element. | 831 // If this changed the official playback position, then queue a task |
| 832 // to fire a simple event named timeupdate at the media element. |
| 817 // FIXME: Add support for firing this event. | 833 // FIXME: Add support for firing this event. |
| 818 | 834 |
| 819 // 4.9 - Set the initial playback position to 0. | 835 // 4.9 - Set the initial playback position to 0. |
| 820 // FIXME: Make this less subtle. The position only becomes 0 because the rea
dy state is HAVE_NOTHING. | 836 // FIXME: Make this less subtle. The position only becomes 0 because the |
| 837 // ready state is HAVE_NOTHING. |
| 821 invalidateCachedTime(); | 838 invalidateCachedTime(); |
| 822 | 839 |
| 823 // 4.10 - Set the timeline offset to Not-a-Number (NaN). | 840 // 4.10 - Set the timeline offset to Not-a-Number (NaN). |
| 824 // 4.11 - Update the duration attribute to Not-a-Number (NaN). | 841 // 4.11 - Update the duration attribute to Not-a-Number (NaN). |
| 825 | 842 |
| 826 cueTimeline().updateActiveCues(0); | 843 cueTimeline().updateActiveCues(0); |
| 827 } else if (!m_paused) { | 844 } else if (!m_paused) { |
| 828 // TODO(foolip): There is a proposal to always reset the paused state | 845 // TODO(foolip): There is a proposal to always reset the paused state |
| 829 // in the media element load algorithm, to avoid a bogus play() promise | 846 // in the media element load algorithm, to avoid a bogus play() promise |
| 830 // rejection: https://github.com/whatwg/html/issues/869 | 847 // rejection: https://github.com/whatwg/html/issues/869 |
| 831 // This is where that change would have an effect, and it is measured to | 848 // This is where that change would have an effect, and it is measured to |
| 832 // verify the assumption that it's a very rare situation. | 849 // verify the assumption that it's a very rare situation. |
| 833 UseCounter::count(document(), | 850 UseCounter::count(document(), |
| 834 UseCounter::HTMLMediaElementLoadNetworkEmptyNotPaused); | 851 UseCounter::HTMLMediaElementLoadNetworkEmptyNotPaused); |
| 835 } | 852 } |
| 836 | 853 |
| 837 // 7 - Set the playbackRate attribute to the value of the defaultPlaybackRate
attribute. | 854 // 7 - Set the playbackRate attribute to the value of the defaultPlaybackRate |
| 855 // attribute. |
| 838 setPlaybackRate(defaultPlaybackRate()); | 856 setPlaybackRate(defaultPlaybackRate()); |
| 839 | 857 |
| 840 // 8 - Set the error attribute to null and the autoplaying flag to true. | 858 // 8 - Set the error attribute to null and the autoplaying flag to true. |
| 841 m_error = nullptr; | 859 m_error = nullptr; |
| 842 m_autoplaying = true; | 860 m_autoplaying = true; |
| 843 | 861 |
| 844 // 9 - Invoke the media element's resource selection algorithm. | 862 // 9 - Invoke the media element's resource selection algorithm. |
| 845 invokeResourceSelectionAlgorithm(); | 863 invokeResourceSelectionAlgorithm(); |
| 846 | 864 |
| 847 // 10 - Note: Playback of any previously playing media resource for this eleme
nt stops. | 865 // 10 - Note: Playback of any previously playing media resource for this |
| 866 // element stops. |
| 848 } | 867 } |
| 849 | 868 |
| 850 void HTMLMediaElement::invokeResourceSelectionAlgorithm() { | 869 void HTMLMediaElement::invokeResourceSelectionAlgorithm() { |
| 851 BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; | 870 BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; |
| 852 // The resource selection algorithm | 871 // The resource selection algorithm |
| 853 // 1 - Set the networkState to NETWORK_NO_SOURCE | 872 // 1 - Set the networkState to NETWORK_NO_SOURCE |
| 854 setNetworkState(kNetworkNoSource); | 873 setNetworkState(kNetworkNoSource); |
| 855 | 874 |
| 856 // 2 - Set the element's show poster flag to true | 875 // 2 - Set the element's show poster flag to true |
| 857 // TODO(srirama.m): Introduce show poster flag and update it as per spec | 876 // TODO(srirama.m): Introduce show poster flag and update it as per spec |
| 858 | 877 |
| 859 m_playedTimeRanges = TimeRanges::create(); | 878 m_playedTimeRanges = TimeRanges::create(); |
| 860 | 879 |
| 861 // FIXME: Investigate whether these can be moved into m_networkState != kNetwo
rkEmpty block above | 880 // FIXME: Investigate whether these can be moved into m_networkState != |
| 881 // kNetworkEmpty block above |
| 862 // so they are closer to the relevant spec steps. | 882 // so they are closer to the relevant spec steps. |
| 863 m_lastSeekTime = 0; | 883 m_lastSeekTime = 0; |
| 864 m_duration = std::numeric_limits<double>::quiet_NaN(); | 884 m_duration = std::numeric_limits<double>::quiet_NaN(); |
| 865 | 885 |
| 866 // 3 - Set the media element's delaying-the-load-event flag to true (this dela
ys the load event) | 886 // 3 - Set the media element's delaying-the-load-event flag to true (this |
| 887 // delays the load event) |
| 867 setShouldDelayLoadEvent(true); | 888 setShouldDelayLoadEvent(true); |
| 868 if (mediaControls()) | 889 if (mediaControls()) |
| 869 mediaControls()->reset(); | 890 mediaControls()->reset(); |
| 870 | 891 |
| 871 // 4 - Await a stable state, allowing the task that invoked this algorithm to
continue | 892 // 4 - Await a stable state, allowing the task that invoked this algorithm to |
| 872 // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask inst
ead. | 893 // continue |
| 873 // See http://crbug.com/593289 for more details. | 894 // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask |
| 895 // instead. See http://crbug.com/593289 for more details. |
| 874 scheduleNextSourceChild(); | 896 scheduleNextSourceChild(); |
| 875 } | 897 } |
| 876 | 898 |
| 877 void HTMLMediaElement::loadInternal() { | 899 void HTMLMediaElement::loadInternal() { |
| 878 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose m
ode was not in the | 900 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose |
| 879 // disabled state when the element's resource selection algorithm last started
". | 901 // mode was not in the disabled state when the element's resource selection |
| 902 // algorithm last started". |
| 880 m_textTracksWhenResourceSelectionBegan.clear(); | 903 m_textTracksWhenResourceSelectionBegan.clear(); |
| 881 if (m_textTracks) { | 904 if (m_textTracks) { |
| 882 for (unsigned i = 0; i < m_textTracks->length(); ++i) { | 905 for (unsigned i = 0; i < m_textTracks->length(); ++i) { |
| 883 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); | 906 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); |
| 884 if (track->mode() != TextTrack::disabledKeyword()) | 907 if (track->mode() != TextTrack::disabledKeyword()) |
| 885 m_textTracksWhenResourceSelectionBegan.append(track); | 908 m_textTracksWhenResourceSelectionBegan.append(track); |
| 886 } | 909 } |
| 887 } | 910 } |
| 888 | 911 |
| 889 selectMediaResource(); | 912 selectMediaResource(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 updateDisplayState(); | 946 updateDisplayState(); |
| 924 | 947 |
| 925 BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this | 948 BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this |
| 926 << "), nothing to load"; | 949 << "), nothing to load"; |
| 927 return; | 950 return; |
| 928 } | 951 } |
| 929 | 952 |
| 930 // 7 - Set the media element's networkState to NETWORK_LOADING. | 953 // 7 - Set the media element's networkState to NETWORK_LOADING. |
| 931 setNetworkState(kNetworkLoading); | 954 setNetworkState(kNetworkLoading); |
| 932 | 955 |
| 933 // 8 - Queue a task to fire a simple event named loadstart at the media elemen
t. | 956 // 8 - Queue a task to fire a simple event named loadstart at the media |
| 957 // element. |
| 934 scheduleEvent(EventTypeNames::loadstart); | 958 scheduleEvent(EventTypeNames::loadstart); |
| 935 | 959 |
| 936 // 9 - Run the appropriate steps... | 960 // 9 - Run the appropriate steps... |
| 937 switch (mode) { | 961 switch (mode) { |
| 938 case Object: | 962 case Object: |
| 939 loadSourceFromObject(); | 963 loadSourceFromObject(); |
| 940 BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this | 964 BLINK_MEDIA_LOG << "selectMediaResource(" << (void*)this |
| 941 << ", using 'srcObject' attribute"; | 965 << ", using 'srcObject' attribute"; |
| 942 break; | 966 break; |
| 943 case Attribute: | 967 case Attribute: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 962 // No type is available when the resource comes from the 'srcObject' | 986 // No type is available when the resource comes from the 'srcObject' |
| 963 // attribute. | 987 // attribute. |
| 964 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), | 988 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), |
| 965 ContentType((String()))); | 989 ContentType((String()))); |
| 966 } | 990 } |
| 967 | 991 |
| 968 void HTMLMediaElement::loadSourceFromAttribute() { | 992 void HTMLMediaElement::loadSourceFromAttribute() { |
| 969 m_loadState = LoadingFromSrcAttr; | 993 m_loadState = LoadingFromSrcAttr; |
| 970 const AtomicString& srcValue = fastGetAttribute(srcAttr); | 994 const AtomicString& srcValue = fastGetAttribute(srcAttr); |
| 971 | 995 |
| 972 // If the src attribute's value is the empty string ... jump down to the faile
d step below | 996 // If the src attribute's value is the empty string ... jump down to the |
| 997 // failed step below |
| 973 if (srcValue.isEmpty()) { | 998 if (srcValue.isEmpty()) { |
| 974 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 999 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 975 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this | 1000 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this |
| 976 << "), empty 'src'"; | 1001 << "), empty 'src'"; |
| 977 return; | 1002 return; |
| 978 } | 1003 } |
| 979 | 1004 |
| 980 KURL mediaURL = document().completeURL(srcValue); | 1005 KURL mediaURL = document().completeURL(srcValue); |
| 981 if (!isSafeToLoadURL(mediaURL, Complain)) { | 1006 if (!isSafeToLoadURL(mediaURL, Complain)) { |
| 982 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 1007 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 if (!frame) { | 1044 if (!frame) { |
| 1020 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 1045 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 1021 return; | 1046 return; |
| 1022 } | 1047 } |
| 1023 | 1048 |
| 1024 // The resource fetch algorithm | 1049 // The resource fetch algorithm |
| 1025 setNetworkState(kNetworkLoading); | 1050 setNetworkState(kNetworkLoading); |
| 1026 | 1051 |
| 1027 m_autoplayHelper->loadingStarted(); | 1052 m_autoplayHelper->loadingStarted(); |
| 1028 | 1053 |
| 1029 // Set m_currentSrc *before* changing to the cache url, the fact that we are l
oading from the app | 1054 // Set m_currentSrc *before* changing to the cache url, the fact that we are |
| 1030 // cache is an internal detail not exposed through the media element API. | 1055 // loading from the app cache is an internal detail not exposed through the |
| 1056 // media element API. |
| 1031 m_currentSrc = url; | 1057 m_currentSrc = url; |
| 1032 | 1058 |
| 1033 if (m_audioSourceNode) | 1059 if (m_audioSourceNode) |
| 1034 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); | 1060 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); |
| 1035 | 1061 |
| 1036 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - m_currentSrc -> " | 1062 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - m_currentSrc -> " |
| 1037 << urlForLoggingMedia(m_currentSrc); | 1063 << urlForLoggingMedia(m_currentSrc); |
| 1038 | 1064 |
| 1039 startProgressEventTimer(); | 1065 startProgressEventTimer(); |
| 1040 | 1066 |
| 1041 // Reset display mode to force a recalculation of what to show because we are
resetting the player. | 1067 // Reset display mode to force a recalculation of what to show because we are |
| 1068 // resetting the player. |
| 1042 setDisplayMode(Unknown); | 1069 setDisplayMode(Unknown); |
| 1043 | 1070 |
| 1044 setPlayerPreload(); | 1071 setPlayerPreload(); |
| 1045 | 1072 |
| 1046 if (fastHasAttribute(mutedAttr)) | 1073 if (fastHasAttribute(mutedAttr)) |
| 1047 m_muted = true; | 1074 m_muted = true; |
| 1048 updateVolume(); | 1075 updateVolume(); |
| 1049 | 1076 |
| 1050 DCHECK(!m_mediaSource); | 1077 DCHECK(!m_mediaSource); |
| 1051 | 1078 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1071 BLINK_MEDIA_LOG << "loadResource(" << (void*)this | 1098 BLINK_MEDIA_LOG << "loadResource(" << (void*)this |
| 1072 << ") : Delaying load because preload == 'none'"; | 1099 << ") : Delaying load because preload == 'none'"; |
| 1073 deferLoad(); | 1100 deferLoad(); |
| 1074 } else { | 1101 } else { |
| 1075 startPlayerLoad(); | 1102 startPlayerLoad(); |
| 1076 } | 1103 } |
| 1077 } else { | 1104 } else { |
| 1078 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 1105 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 1079 } | 1106 } |
| 1080 | 1107 |
| 1081 // If there is no poster to display, allow the media engine to render video fr
ames as soon as | 1108 // If there is no poster to display, allow the media engine to render video |
| 1082 // they are available. | 1109 // frames as soon as they are available. |
| 1083 updateDisplayState(); | 1110 updateDisplayState(); |
| 1084 | 1111 |
| 1085 if (layoutObject()) | 1112 if (layoutObject()) |
| 1086 layoutObject()->updateFromElement(); | 1113 layoutObject()->updateFromElement(); |
| 1087 } | 1114 } |
| 1088 | 1115 |
| 1089 void HTMLMediaElement::startPlayerLoad(const KURL& playerProvidedUrl) { | 1116 void HTMLMediaElement::startPlayerLoad(const KURL& playerProvidedUrl) { |
| 1090 DCHECK(!m_webMediaPlayer); | 1117 DCHECK(!m_webMediaPlayer); |
| 1091 | 1118 |
| 1092 WebMediaPlayerSource source; | 1119 WebMediaPlayerSource source; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 | 1154 |
| 1128 m_webMediaPlayer = | 1155 m_webMediaPlayer = |
| 1129 frame->loader().client()->createWebMediaPlayer(*this, source, this); | 1156 frame->loader().client()->createWebMediaPlayer(*this, source, this); |
| 1130 if (!m_webMediaPlayer) { | 1157 if (!m_webMediaPlayer) { |
| 1131 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 1158 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 1132 return; | 1159 return; |
| 1133 } | 1160 } |
| 1134 | 1161 |
| 1135 if (layoutObject()) | 1162 if (layoutObject()) |
| 1136 layoutObject()->setShouldDoFullPaintInvalidation(); | 1163 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 1137 // Make sure if we create/re-create the WebMediaPlayer that we update our wrap
per. | 1164 // Make sure if we create/re-create the WebMediaPlayer that we update our |
| 1165 // wrapper. |
| 1138 m_audioSourceProvider.wrap(m_webMediaPlayer->getAudioSourceProvider()); | 1166 m_audioSourceProvider.wrap(m_webMediaPlayer->getAudioSourceProvider()); |
| 1139 m_webMediaPlayer->setVolume(effectiveMediaVolume()); | 1167 m_webMediaPlayer->setVolume(effectiveMediaVolume()); |
| 1140 | 1168 |
| 1141 m_webMediaPlayer->setPoster(posterImageURL()); | 1169 m_webMediaPlayer->setPoster(posterImageURL()); |
| 1142 | 1170 |
| 1143 m_webMediaPlayer->setPreload(effectivePreloadType()); | 1171 m_webMediaPlayer->setPreload(effectivePreloadType()); |
| 1144 | 1172 |
| 1145 m_webMediaPlayer->load(loadType(), source, corsMode()); | 1173 m_webMediaPlayer->load(loadType(), source, corsMode()); |
| 1146 | 1174 |
| 1147 if (isFullscreen()) { | 1175 if (isFullscreen()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 void HTMLMediaElement::cancelDeferredLoad() { | 1208 void HTMLMediaElement::cancelDeferredLoad() { |
| 1181 m_deferredLoadTimer.stop(); | 1209 m_deferredLoadTimer.stop(); |
| 1182 m_deferredLoadState = NotDeferred; | 1210 m_deferredLoadState = NotDeferred; |
| 1183 } | 1211 } |
| 1184 | 1212 |
| 1185 void HTMLMediaElement::executeDeferredLoad() { | 1213 void HTMLMediaElement::executeDeferredLoad() { |
| 1186 DCHECK_GE(m_deferredLoadState, WaitingForTrigger); | 1214 DCHECK_GE(m_deferredLoadState, WaitingForTrigger); |
| 1187 | 1215 |
| 1188 // resource fetch algorithm step 3 - continued from deferLoad(). | 1216 // resource fetch algorithm step 3 - continued from deferLoad(). |
| 1189 | 1217 |
| 1190 // 5. Wait for an implementation-defined event (e.g. the user requesting that
the media element begin playback). | 1218 // 5. Wait for an implementation-defined event (e.g. the user requesting that |
| 1191 // This is assumed to be whatever 'event' ended up calling this method. | 1219 // the media element begin playback). This is assumed to be whatever 'event' |
| 1220 // ended up calling this method. |
| 1192 cancelDeferredLoad(); | 1221 cancelDeferredLoad(); |
| 1193 // 6. Set the element's delaying-the-load-event flag back to true (this | 1222 // 6. Set the element's delaying-the-load-event flag back to true (this |
| 1194 // delays the load event again, in case it hasn't been fired yet). | 1223 // delays the load event again, in case it hasn't been fired yet). |
| 1195 setShouldDelayLoadEvent(true); | 1224 setShouldDelayLoadEvent(true); |
| 1196 // 7. Set the networkState to NETWORK_LOADING. | 1225 // 7. Set the networkState to NETWORK_LOADING. |
| 1197 setNetworkState(kNetworkLoading); | 1226 setNetworkState(kNetworkLoading); |
| 1198 | 1227 |
| 1199 startProgressEventTimer(); | 1228 startProgressEventTimer(); |
| 1200 | 1229 |
| 1201 startPlayerLoad(); | 1230 startPlayerLoad(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1230 if (m_srcObject || | 1259 if (m_srcObject || |
| 1231 (!m_currentSrc.isNull() && isMediaStreamURL(m_currentSrc.getString()))) | 1260 (!m_currentSrc.isNull() && isMediaStreamURL(m_currentSrc.getString()))) |
| 1232 return WebMediaPlayer::LoadTypeMediaStream; | 1261 return WebMediaPlayer::LoadTypeMediaStream; |
| 1233 | 1262 |
| 1234 return WebMediaPlayer::LoadTypeURL; | 1263 return WebMediaPlayer::LoadTypeURL; |
| 1235 } | 1264 } |
| 1236 | 1265 |
| 1237 bool HTMLMediaElement::textTracksAreReady() const { | 1266 bool HTMLMediaElement::textTracksAreReady() const { |
| 1238 // 4.8.10.12.1 Text track model | 1267 // 4.8.10.12.1 Text track model |
| 1239 // ... | 1268 // ... |
| 1240 // The text tracks of a media element are ready if all the text tracks whose m
ode was not | 1269 // The text tracks of a media element are ready if all the text tracks whose |
| 1241 // in the disabled state when the element's resource selection algorithm last
started now | 1270 // mode was not in the disabled state when the element's resource selection |
| 1242 // have a text track readiness state of loaded or failed to load. | 1271 // algorithm last started now have a text track readiness state of loaded or |
| 1272 // failed to load. |
| 1243 for (unsigned i = 0; i < m_textTracksWhenResourceSelectionBegan.size(); ++i) { | 1273 for (unsigned i = 0; i < m_textTracksWhenResourceSelectionBegan.size(); ++i) { |
| 1244 if (m_textTracksWhenResourceSelectionBegan[i]->getReadinessState() == | 1274 if (m_textTracksWhenResourceSelectionBegan[i]->getReadinessState() == |
| 1245 TextTrack::Loading || | 1275 TextTrack::Loading || |
| 1246 m_textTracksWhenResourceSelectionBegan[i]->getReadinessState() == | 1276 m_textTracksWhenResourceSelectionBegan[i]->getReadinessState() == |
| 1247 TextTrack::NotLoaded) | 1277 TextTrack::NotLoaded) |
| 1248 return false; | 1278 return false; |
| 1249 } | 1279 } |
| 1250 | 1280 |
| 1251 return true; | 1281 return true; |
| 1252 } | 1282 } |
| 1253 | 1283 |
| 1254 void HTMLMediaElement::textTrackReadyStateChanged(TextTrack* track) { | 1284 void HTMLMediaElement::textTrackReadyStateChanged(TextTrack* track) { |
| 1255 if (webMediaPlayer() && | 1285 if (webMediaPlayer() && |
| 1256 m_textTracksWhenResourceSelectionBegan.contains(track)) { | 1286 m_textTracksWhenResourceSelectionBegan.contains(track)) { |
| 1257 if (track->getReadinessState() != TextTrack::Loading) | 1287 if (track->getReadinessState() != TextTrack::Loading) |
| 1258 setReadyState(static_cast<ReadyState>(webMediaPlayer()->getReadyState())); | 1288 setReadyState(static_cast<ReadyState>(webMediaPlayer()->getReadyState())); |
| 1259 } else { | 1289 } else { |
| 1260 // The track readiness state might have changed as a result of the user | 1290 // The track readiness state might have changed as a result of the user |
| 1261 // clicking the captions button. In this case, a check whether all the | 1291 // clicking the captions button. In this case, a check whether all the |
| 1262 // resources have failed loading should be done in order to hide the CC butt
on. | 1292 // resources have failed loading should be done in order to hide the CC |
| 1293 // button. |
| 1263 if (mediaControls() && | 1294 if (mediaControls() && |
| 1264 track->getReadinessState() == TextTrack::FailedToLoad) | 1295 track->getReadinessState() == TextTrack::FailedToLoad) |
| 1265 mediaControls()->refreshClosedCaptionsButtonVisibility(); | 1296 mediaControls()->refreshClosedCaptionsButtonVisibility(); |
| 1266 } | 1297 } |
| 1267 } | 1298 } |
| 1268 | 1299 |
| 1269 void HTMLMediaElement::textTrackModeChanged(TextTrack* track) { | 1300 void HTMLMediaElement::textTrackModeChanged(TextTrack* track) { |
| 1270 // Mark this track as "configured" so configureTextTracks won't change the mod
e again. | 1301 // Mark this track as "configured" so configureTextTracks won't change the |
| 1302 // mode again. |
| 1271 if (track->trackType() == TextTrack::TrackElement) | 1303 if (track->trackType() == TextTrack::TrackElement) |
| 1272 track->setHasBeenConfigured(true); | 1304 track->setHasBeenConfigured(true); |
| 1273 | 1305 |
| 1274 configureTextTrackDisplay(); | 1306 configureTextTrackDisplay(); |
| 1275 | 1307 |
| 1276 DCHECK(textTracks()->contains(track)); | 1308 DCHECK(textTracks()->contains(track)); |
| 1277 textTracks()->scheduleChangeEvent(); | 1309 textTracks()->scheduleChangeEvent(); |
| 1278 } | 1310 } |
| 1279 | 1311 |
| 1280 void HTMLMediaElement::disableAutomaticTextTrackSelection() { | 1312 void HTMLMediaElement::disableAutomaticTextTrackSelection() { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 // 350ms is not magic, it is in the spec! | 1363 // 350ms is not magic, it is in the spec! |
| 1332 m_progressEventTimer.startRepeating(0.350, BLINK_FROM_HERE); | 1364 m_progressEventTimer.startRepeating(0.350, BLINK_FROM_HERE); |
| 1333 } | 1365 } |
| 1334 | 1366 |
| 1335 void HTMLMediaElement::waitForSourceChange() { | 1367 void HTMLMediaElement::waitForSourceChange() { |
| 1336 BLINK_MEDIA_LOG << "waitForSourceChange(" << (void*)this << ")"; | 1368 BLINK_MEDIA_LOG << "waitForSourceChange(" << (void*)this << ")"; |
| 1337 | 1369 |
| 1338 stopPeriodicTimers(); | 1370 stopPeriodicTimers(); |
| 1339 m_loadState = WaitingForSource; | 1371 m_loadState = WaitingForSource; |
| 1340 | 1372 |
| 1341 // 6.17 - Waiting: Set the element's networkState attribute to the NETWORK_NO_
SOURCE value | 1373 // 6.17 - Waiting: Set the element's networkState attribute to the |
| 1374 // NETWORK_NO_SOURCE value |
| 1342 setNetworkState(kNetworkNoSource); | 1375 setNetworkState(kNetworkNoSource); |
| 1343 | 1376 |
| 1344 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops
delaying the load event. | 1377 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops |
| 1378 // delaying the load event. |
| 1345 setShouldDelayLoadEvent(false); | 1379 setShouldDelayLoadEvent(false); |
| 1346 | 1380 |
| 1347 updateDisplayState(); | 1381 updateDisplayState(); |
| 1348 | 1382 |
| 1349 if (layoutObject()) | 1383 if (layoutObject()) |
| 1350 layoutObject()->updateFromElement(); | 1384 layoutObject()->updateFromElement(); |
| 1351 } | 1385 } |
| 1352 | 1386 |
| 1353 void HTMLMediaElement::noneSupported() { | 1387 void HTMLMediaElement::noneSupported() { |
| 1354 BLINK_MEDIA_LOG << "noneSupported(" << (void*)this << ")"; | 1388 BLINK_MEDIA_LOG << "noneSupported(" << (void*)this << ")"; |
| 1355 | 1389 |
| 1356 stopPeriodicTimers(); | 1390 stopPeriodicTimers(); |
| 1357 m_loadState = WaitingForSource; | 1391 m_loadState = WaitingForSource; |
| 1358 m_currentSourceNode = nullptr; | 1392 m_currentSourceNode = nullptr; |
| 1359 | 1393 |
| 1360 // 4.8.13.5 | 1394 // 4.8.13.5 |
| 1361 // The dedicated media source failure steps are the following steps: | 1395 // The dedicated media source failure steps are the following steps: |
| 1362 | 1396 |
| 1363 // 1 - Set the error attribute to a new MediaError object whose code attribute
is set to | 1397 // 1 - Set the error attribute to a new MediaError object whose code attribute |
| 1364 // MEDIA_ERR_SRC_NOT_SUPPORTED. | 1398 // is set to MEDIA_ERR_SRC_NOT_SUPPORTED. |
| 1365 m_error = MediaError::create(MediaError::kMediaErrSrcNotSupported); | 1399 m_error = MediaError::create(MediaError::kMediaErrSrcNotSupported); |
| 1366 | 1400 |
| 1367 // 2 - Forget the media element's media-resource-specific text tracks. | 1401 // 2 - Forget the media element's media-resource-specific text tracks. |
| 1368 forgetResourceSpecificTracks(); | 1402 forgetResourceSpecificTracks(); |
| 1369 | 1403 |
| 1370 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value
. | 1404 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE |
| 1405 // value. |
| 1371 setNetworkState(kNetworkNoSource); | 1406 setNetworkState(kNetworkNoSource); |
| 1372 | 1407 |
| 1373 // 4 - Set the element's show poster flag to true. | 1408 // 4 - Set the element's show poster flag to true. |
| 1374 updateDisplayState(); | 1409 updateDisplayState(); |
| 1375 | 1410 |
| 1376 // 5 - Fire a simple event named error at the media element. | 1411 // 5 - Fire a simple event named error at the media element. |
| 1377 scheduleEvent(EventTypeNames::error); | 1412 scheduleEvent(EventTypeNames::error); |
| 1378 | 1413 |
| 1379 // 6 - Reject pending play promises with NotSupportedError. | 1414 // 6 - Reject pending play promises with NotSupportedError. |
| 1380 scheduleRejectPlayPromises(NotSupportedError); | 1415 scheduleRejectPlayPromises(NotSupportedError); |
| 1381 | 1416 |
| 1382 closeMediaSource(); | 1417 closeMediaSource(); |
| 1383 | 1418 |
| 1384 // 7 - Set the element's delaying-the-load-event flag to false. This stops del
aying the load event. | 1419 // 7 - Set the element's delaying-the-load-event flag to false. This stops |
| 1420 // delaying the load event. |
| 1385 setShouldDelayLoadEvent(false); | 1421 setShouldDelayLoadEvent(false); |
| 1386 | 1422 |
| 1387 if (layoutObject()) | 1423 if (layoutObject()) |
| 1388 layoutObject()->updateFromElement(); | 1424 layoutObject()->updateFromElement(); |
| 1389 } | 1425 } |
| 1390 | 1426 |
| 1391 void HTMLMediaElement::mediaEngineError(MediaError* err) { | 1427 void HTMLMediaElement::mediaEngineError(MediaError* err) { |
| 1392 DCHECK_GE(m_readyState, kHaveMetadata); | 1428 DCHECK_GE(m_readyState, kHaveMetadata); |
| 1393 BLINK_MEDIA_LOG << "mediaEngineError(" << (void*)this << ", " | 1429 BLINK_MEDIA_LOG << "mediaEngineError(" << (void*)this << ", " |
| 1394 << static_cast<int>(err->code()) << ")"; | 1430 << static_cast<int>(err->code()) << ")"; |
| 1395 | 1431 |
| 1396 // 1 - The user agent should cancel the fetching process. | 1432 // 1 - The user agent should cancel the fetching process. |
| 1397 stopPeriodicTimers(); | 1433 stopPeriodicTimers(); |
| 1398 m_loadState = WaitingForSource; | 1434 m_loadState = WaitingForSource; |
| 1399 | 1435 |
| 1400 // 2 - Set the error attribute to a new MediaError object whose code attribute
is | 1436 // 2 - Set the error attribute to a new MediaError object whose code attribute |
| 1401 // set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE. | 1437 // is set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE. |
| 1402 m_error = err; | 1438 m_error = err; |
| 1403 | 1439 |
| 1404 // 3 - Queue a task to fire a simple event named error at the media element. | 1440 // 3 - Queue a task to fire a simple event named error at the media element. |
| 1405 scheduleEvent(EventTypeNames::error); | 1441 scheduleEvent(EventTypeNames::error); |
| 1406 | 1442 |
| 1407 // 4 - Set the element's networkState attribute to the NETWORK_IDLE value. | 1443 // 4 - Set the element's networkState attribute to the NETWORK_IDLE value. |
| 1408 setNetworkState(kNetworkIdle); | 1444 setNetworkState(kNetworkIdle); |
| 1409 | 1445 |
| 1410 // 5 - Set the element's delaying-the-load-event flag to false. This stops del
aying the load event. | 1446 // 5 - Set the element's delaying-the-load-event flag to false. This stops |
| 1447 // delaying the load event. |
| 1411 setShouldDelayLoadEvent(false); | 1448 setShouldDelayLoadEvent(false); |
| 1412 | 1449 |
| 1413 // 6 - Abort the overall resource selection algorithm. | 1450 // 6 - Abort the overall resource selection algorithm. |
| 1414 m_currentSourceNode = nullptr; | 1451 m_currentSourceNode = nullptr; |
| 1415 } | 1452 } |
| 1416 | 1453 |
| 1417 void HTMLMediaElement::cancelPendingEventsAndCallbacks() { | 1454 void HTMLMediaElement::cancelPendingEventsAndCallbacks() { |
| 1418 BLINK_MEDIA_LOG << "cancelPendingEventsAndCallbacks(" << (void*)this << ")"; | 1455 BLINK_MEDIA_LOG << "cancelPendingEventsAndCallbacks(" << (void*)this << ")"; |
| 1419 m_asyncEventQueue->cancelAllEvents(); | 1456 m_asyncEventQueue->cancelAllEvents(); |
| 1420 | 1457 |
| 1421 for (HTMLSourceElement* source = | 1458 for (HTMLSourceElement* source = |
| 1422 Traversal<HTMLSourceElement>::firstChild(*this); | 1459 Traversal<HTMLSourceElement>::firstChild(*this); |
| 1423 source; source = Traversal<HTMLSourceElement>::nextSibling(*source)) | 1460 source; source = Traversal<HTMLSourceElement>::nextSibling(*source)) |
| 1424 source->cancelPendingErrorEvent(); | 1461 source->cancelPendingErrorEvent(); |
| 1425 } | 1462 } |
| 1426 | 1463 |
| 1427 void HTMLMediaElement::networkStateChanged() { | 1464 void HTMLMediaElement::networkStateChanged() { |
| 1428 setNetworkState(webMediaPlayer()->getNetworkState()); | 1465 setNetworkState(webMediaPlayer()->getNetworkState()); |
| 1429 } | 1466 } |
| 1430 | 1467 |
| 1431 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) { | 1468 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) { |
| 1432 stopPeriodicTimers(); | 1469 stopPeriodicTimers(); |
| 1433 | 1470 |
| 1434 // If we failed while trying to load a <source> element, the movie was never p
arsed, and there are more | 1471 // If we failed while trying to load a <source> element, the movie was never |
| 1435 // <source> children, schedule the next one | 1472 // parsed, and there are more <source> children, schedule the next one |
| 1436 if (m_readyState < kHaveMetadata && m_loadState == LoadingFromSourceElement) { | 1473 if (m_readyState < kHaveMetadata && m_loadState == LoadingFromSourceElement) { |
| 1437 // resource selection algorithm | 1474 // resource selection algorithm |
| 1438 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM ma
nipulation task source, to fire a simple event named error at the candidate elem
ent. | 1475 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM |
| 1476 // manipulation task source, to fire a simple event named error at the |
| 1477 // candidate element. |
| 1439 if (m_currentSourceNode) | 1478 if (m_currentSourceNode) |
| 1440 m_currentSourceNode->scheduleErrorEvent(); | 1479 m_currentSourceNode->scheduleErrorEvent(); |
| 1441 else | 1480 else |
| 1442 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this | 1481 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this |
| 1443 << ") - error event not sent, <source> was removed"; | 1482 << ") - error event not sent, <source> was removed"; |
| 1444 | 1483 |
| 1445 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous sec
tion consists of all the remaining steps of this algorithm until the algorithm s
ays the synchronous section has ended. | 1484 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous |
| 1485 // section consists of all the remaining steps of this algorithm until the |
| 1486 // algorithm says the synchronous section has ended. |
| 1446 | 1487 |
| 1447 // 9.Otherwise.11 - Forget the media element's media-resource-specific track
s. | 1488 // 9.Otherwise.11 - Forget the media element's media-resource-specific |
| 1489 // tracks. |
| 1448 forgetResourceSpecificTracks(); | 1490 forgetResourceSpecificTracks(); |
| 1449 | 1491 |
| 1450 if (havePotentialSourceChild()) { | 1492 if (havePotentialSourceChild()) { |
| 1451 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this | 1493 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this |
| 1452 << ") - scheduling next <source>"; | 1494 << ") - scheduling next <source>"; |
| 1453 scheduleNextSourceChild(); | 1495 scheduleNextSourceChild(); |
| 1454 } else { | 1496 } else { |
| 1455 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this | 1497 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this |
| 1456 << ") - no more <source> elements, waiting"; | 1498 << ") - no more <source> elements, waiting"; |
| 1457 waitForSourceChange(); | 1499 waitForSourceChange(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 | 1569 |
| 1528 void HTMLMediaElement::readyStateChanged() { | 1570 void HTMLMediaElement::readyStateChanged() { |
| 1529 setReadyState(static_cast<ReadyState>(webMediaPlayer()->getReadyState())); | 1571 setReadyState(static_cast<ReadyState>(webMediaPlayer()->getReadyState())); |
| 1530 } | 1572 } |
| 1531 | 1573 |
| 1532 void HTMLMediaElement::setReadyState(ReadyState state) { | 1574 void HTMLMediaElement::setReadyState(ReadyState state) { |
| 1533 BLINK_MEDIA_LOG << "setReadyState(" << (void*)this << ", " | 1575 BLINK_MEDIA_LOG << "setReadyState(" << (void*)this << ", " |
| 1534 << static_cast<int>(state) << ") - current state is " | 1576 << static_cast<int>(state) << ") - current state is " |
| 1535 << static_cast<int>(m_readyState); | 1577 << static_cast<int>(m_readyState); |
| 1536 | 1578 |
| 1537 // Set "wasPotentiallyPlaying" BEFORE updating m_readyState, potentiallyPlayin
g() uses it | 1579 // Set "wasPotentiallyPlaying" BEFORE updating m_readyState, |
| 1580 // potentiallyPlaying() uses it |
| 1538 bool wasPotentiallyPlaying = potentiallyPlaying(); | 1581 bool wasPotentiallyPlaying = potentiallyPlaying(); |
| 1539 | 1582 |
| 1540 ReadyState oldState = m_readyState; | 1583 ReadyState oldState = m_readyState; |
| 1541 ReadyState newState = state; | 1584 ReadyState newState = state; |
| 1542 | 1585 |
| 1543 bool tracksAreReady = textTracksAreReady(); | 1586 bool tracksAreReady = textTracksAreReady(); |
| 1544 | 1587 |
| 1545 if (newState == oldState && m_tracksAreReady == tracksAreReady) | 1588 if (newState == oldState && m_tracksAreReady == tracksAreReady) |
| 1546 return; | 1589 return; |
| 1547 | 1590 |
| 1548 m_tracksAreReady = tracksAreReady; | 1591 m_tracksAreReady = tracksAreReady; |
| 1549 | 1592 |
| 1550 if (tracksAreReady) { | 1593 if (tracksAreReady) { |
| 1551 m_readyState = newState; | 1594 m_readyState = newState; |
| 1552 } else { | 1595 } else { |
| 1553 // If a media file has text tracks the readyState may not progress beyond kH
aveFutureData until | 1596 // If a media file has text tracks the readyState may not progress beyond |
| 1554 // the text tracks are ready, regardless of the state of the media file. | 1597 // kHaveFutureData until the text tracks are ready, regardless of the state |
| 1598 // of the media file. |
| 1555 if (newState <= kHaveMetadata) | 1599 if (newState <= kHaveMetadata) |
| 1556 m_readyState = newState; | 1600 m_readyState = newState; |
| 1557 else | 1601 else |
| 1558 m_readyState = kHaveCurrentData; | 1602 m_readyState = kHaveCurrentData; |
| 1559 } | 1603 } |
| 1560 | 1604 |
| 1561 if (oldState > m_readyStateMaximum) | 1605 if (oldState > m_readyStateMaximum) |
| 1562 m_readyStateMaximum = oldState; | 1606 m_readyStateMaximum = oldState; |
| 1563 | 1607 |
| 1564 if (m_networkState == kNetworkEmpty) | 1608 if (m_networkState == kNetworkEmpty) |
| 1565 return; | 1609 return; |
| 1566 | 1610 |
| 1567 if (m_seeking) { | 1611 if (m_seeking) { |
| 1568 // 4.8.10.9, step 9 note: If the media element was potentially playing immed
iately before | 1612 // 4.8.10.9, step 9 note: If the media element was potentially playing |
| 1569 // it started seeking, but seeking caused its readyState attribute to change
to a value | 1613 // immediately before it started seeking, but seeking caused its readyState |
| 1570 // lower than kHaveFutureData, then a waiting will be fired at the element. | 1614 // attribute to change to a value lower than kHaveFutureData, then a waiting |
| 1615 // will be fired at the element. |
| 1571 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) | 1616 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) |
| 1572 scheduleEvent(EventTypeNames::waiting); | 1617 scheduleEvent(EventTypeNames::waiting); |
| 1573 | 1618 |
| 1574 // 4.8.10.9 steps 12-14 | 1619 // 4.8.10.9 steps 12-14 |
| 1575 if (m_readyState >= kHaveCurrentData) | 1620 if (m_readyState >= kHaveCurrentData) |
| 1576 finishSeek(); | 1621 finishSeek(); |
| 1577 } else { | 1622 } else { |
| 1578 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) { | 1623 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) { |
| 1579 // 4.8.10.8 | 1624 // 4.8.10.8 |
| 1580 scheduleTimeupdateEvent(false); | 1625 scheduleTimeupdateEvent(false); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1738 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. | 1783 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. |
| 1739 // FIXME: remove m_webMediaPlayer check once we figure out how | 1784 // FIXME: remove m_webMediaPlayer check once we figure out how |
| 1740 // m_webMediaPlayer is going out of sync with readystate. | 1785 // m_webMediaPlayer is going out of sync with readystate. |
| 1741 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. | 1786 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. |
| 1742 if (!m_webMediaPlayer || m_readyState == kHaveNothing) | 1787 if (!m_webMediaPlayer || m_readyState == kHaveNothing) |
| 1743 return; | 1788 return; |
| 1744 | 1789 |
| 1745 // Ignore preload none and start load if necessary. | 1790 // Ignore preload none and start load if necessary. |
| 1746 setIgnorePreloadNone(); | 1791 setIgnorePreloadNone(); |
| 1747 | 1792 |
| 1748 // Get the current time before setting m_seeking, m_lastSeekTime is returned o
nce it is set. | 1793 // Get the current time before setting m_seeking, m_lastSeekTime is returned |
| 1794 // once it is set. |
| 1749 refreshCachedTime(); | 1795 refreshCachedTime(); |
| 1750 // This is needed to avoid getting default playback start position from curren
tTime(). | 1796 // This is needed to avoid getting default playback start position from |
| 1797 // currentTime(). |
| 1751 double now = m_cachedTime; | 1798 double now = m_cachedTime; |
| 1752 | 1799 |
| 1753 // 3 - If the element's seeking IDL attribute is true, then another instance o
f this algorithm is | 1800 // 3 - If the element's seeking IDL attribute is true, then another instance |
| 1754 // already running. Abort that other instance of the algorithm without waiting
for the step that | 1801 // of this algorithm is already running. Abort that other instance of the |
| 1755 // it is running to complete. | 1802 // algorithm without waiting for the step that it is running to complete. |
| 1756 // Nothing specific to be done here. | 1803 // Nothing specific to be done here. |
| 1757 | 1804 |
| 1758 // 4 - Set the seeking IDL attribute to true. | 1805 // 4 - Set the seeking IDL attribute to true. |
| 1759 // The flag will be cleared when the engine tells us the time has actually cha
nged. | 1806 // The flag will be cleared when the engine tells us the time has actually |
| 1807 // changed. |
| 1760 m_seeking = true; | 1808 m_seeking = true; |
| 1761 | 1809 |
| 1762 // 6 - If the new playback position is later than the end of the media resourc
e, then let it be the end | 1810 // 6 - If the new playback position is later than the end of the media |
| 1763 // of the media resource instead. | 1811 // resource, then let it be the end of the media resource instead. |
| 1764 time = std::min(time, duration()); | 1812 time = std::min(time, duration()); |
| 1765 | 1813 |
| 1766 // 7 - If the new playback position is less than the earliest possible positio
n, let it be that position instead. | 1814 // 7 - If the new playback position is less than the earliest possible |
| 1815 // position, let it be that position instead. |
| 1767 time = std::max(time, 0.0); | 1816 time = std::max(time, 0.0); |
| 1768 | 1817 |
| 1769 // Ask the media engine for the time value in the movie's time scale before co
mparing with current time. This | 1818 // Ask the media engine for the time value in the movie's time scale before |
| 1770 // is necessary because if the seek time is not equal to currentTime but the d
elta is less than the movie's | 1819 // comparing with current time. This is necessary because if the seek time is |
| 1771 // time scale, we will ask the media engine to "seek" to the current movie tim
e, which may be a noop and | 1820 // not equal to currentTime but the delta is less than the movie's time scale, |
| 1772 // not generate a timechanged callback. This means m_seeking will never be cle
ared and we will never | 1821 // we will ask the media engine to "seek" to the current movie time, which may |
| 1773 // fire a 'seeked' event. | 1822 // be a noop and not generate a timechanged callback. This means m_seeking |
| 1823 // will never be cleared and we will never fire a 'seeked' event. |
| 1774 double mediaTime = webMediaPlayer()->mediaTimeForTimeValue(time); | 1824 double mediaTime = webMediaPlayer()->mediaTimeForTimeValue(time); |
| 1775 if (time != mediaTime) { | 1825 if (time != mediaTime) { |
| 1776 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time | 1826 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time |
| 1777 << ") - media timeline equivalent is " << mediaTime; | 1827 << ") - media timeline equivalent is " << mediaTime; |
| 1778 time = mediaTime; | 1828 time = mediaTime; |
| 1779 } | 1829 } |
| 1780 | 1830 |
| 1781 // 8 - If the (possibly now changed) new playback position is not in one of th
e ranges given in the | 1831 // 8 - If the (possibly now changed) new playback position is not in one of |
| 1782 // seekable attribute, then let it be the position in one of the ranges given
in the seekable attribute | 1832 // the ranges given in the seekable attribute, then let it be the position in |
| 1783 // that is the nearest to the new playback position. ... If there are no range
s given in the seekable | 1833 // one of the ranges given in the seekable attribute that is the nearest to |
| 1784 // attribute then set the seeking IDL attribute to false and abort these steps
. | 1834 // the new playback position. ... If there are no ranges given in the seekable |
| 1835 // attribute then set the seeking IDL attribute to false and abort these |
| 1836 // steps. |
| 1785 TimeRanges* seekableRanges = seekable(); | 1837 TimeRanges* seekableRanges = seekable(); |
| 1786 | 1838 |
| 1787 if (!seekableRanges->length()) { | 1839 if (!seekableRanges->length()) { |
| 1788 m_seeking = false; | 1840 m_seeking = false; |
| 1789 return; | 1841 return; |
| 1790 } | 1842 } |
| 1791 time = seekableRanges->nearest(time, now); | 1843 time = seekableRanges->nearest(time, now); |
| 1792 | 1844 |
| 1793 if (m_playing && m_lastSeekTime < now) | 1845 if (m_playing && m_lastSeekTime < now) |
| 1794 addPlayedRange(m_lastSeekTime, now); | 1846 addPlayedRange(m_lastSeekTime, now); |
| 1795 | 1847 |
| 1796 m_lastSeekTime = time; | 1848 m_lastSeekTime = time; |
| 1797 | 1849 |
| 1798 // 10 - Queue a task to fire a simple event named seeking at the element. | 1850 // 10 - Queue a task to fire a simple event named seeking at the element. |
| 1799 scheduleEvent(EventTypeNames::seeking); | 1851 scheduleEvent(EventTypeNames::seeking); |
| 1800 | 1852 |
| 1801 // 11 - Set the current playback position to the given new playback position. | 1853 // 11 - Set the current playback position to the given new playback position. |
| 1802 webMediaPlayer()->seek(time); | 1854 webMediaPlayer()->seek(time); |
| 1803 | 1855 |
| 1804 // 14-17 are handled, if necessary, when the engine signals a readystate chang
e or otherwise | 1856 // 14-17 are handled, if necessary, when the engine signals a readystate |
| 1805 // satisfies seek completion and signals a time change. | 1857 // change or otherwise satisfies seek completion and signals a time change. |
| 1806 } | 1858 } |
| 1807 | 1859 |
| 1808 void HTMLMediaElement::finishSeek() { | 1860 void HTMLMediaElement::finishSeek() { |
| 1809 BLINK_MEDIA_LOG << "finishSeek(" << (void*)this << ")"; | 1861 BLINK_MEDIA_LOG << "finishSeek(" << (void*)this << ")"; |
| 1810 | 1862 |
| 1811 // 14 - Set the seeking IDL attribute to false. | 1863 // 14 - Set the seeking IDL attribute to false. |
| 1812 m_seeking = false; | 1864 m_seeking = false; |
| 1813 | 1865 |
| 1814 // 16 - Queue a task to fire a simple event named timeupdate at the element. | 1866 // 16 - Queue a task to fire a simple event named timeupdate at the element. |
| 1815 scheduleTimeupdateEvent(false); | 1867 scheduleTimeupdateEvent(false); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1987 String HTMLMediaElement::preload() const { | 2039 String HTMLMediaElement::preload() const { |
| 1988 return preloadTypeToString(preloadType()); | 2040 return preloadTypeToString(preloadType()); |
| 1989 } | 2041 } |
| 1990 | 2042 |
| 1991 void HTMLMediaElement::setPreload(const AtomicString& preload) { | 2043 void HTMLMediaElement::setPreload(const AtomicString& preload) { |
| 1992 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; | 2044 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; |
| 1993 setAttribute(preloadAttr, preload); | 2045 setAttribute(preloadAttr, preload); |
| 1994 } | 2046 } |
| 1995 | 2047 |
| 1996 WebMediaPlayer::Preload HTMLMediaElement::preloadType() const { | 2048 WebMediaPlayer::Preload HTMLMediaElement::preloadType() const { |
| 1997 // Force preload to none for cellular connections or when data saver is explic
itly set. | 2049 // Force preload to none for cellular connections or when data saver is |
| 2050 // explicitly set. |
| 1998 if (networkStateNotifier().isCellularConnectionType() || | 2051 if (networkStateNotifier().isCellularConnectionType() || |
| 1999 (document().settings() && | 2052 (document().settings() && |
| 2000 (document().settings()->dataSaverEnabled() || | 2053 (document().settings()->dataSaverEnabled() || |
| 2001 document().settings()->forcePreloadNoneForMediaElements()))) { | 2054 document().settings()->forcePreloadNoneForMediaElements()))) { |
| 2002 UseCounter::count(document(), | 2055 UseCounter::count(document(), |
| 2003 UseCounter::HTMLMediaElementPreloadForcedNone); | 2056 UseCounter::HTMLMediaElementPreloadForcedNone); |
| 2004 return WebMediaPlayer::PreloadNone; | 2057 return WebMediaPlayer::PreloadNone; |
| 2005 } | 2058 } |
| 2006 | 2059 |
| 2007 const AtomicString& preload = fastGetAttribute(preloadAttr); | 2060 const AtomicString& preload = fastGetAttribute(preloadAttr); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2325 mediaControls()->updateVolume(); | 2378 mediaControls()->updateVolume(); |
| 2326 } | 2379 } |
| 2327 | 2380 |
| 2328 double HTMLMediaElement::effectiveMediaVolume() const { | 2381 double HTMLMediaElement::effectiveMediaVolume() const { |
| 2329 if (m_muted) | 2382 if (m_muted) |
| 2330 return 0; | 2383 return 0; |
| 2331 | 2384 |
| 2332 return m_volume; | 2385 return m_volume; |
| 2333 } | 2386 } |
| 2334 | 2387 |
| 2335 // The spec says to fire periodic timeupdate events (those sent while playing) e
very | 2388 // The spec says to fire periodic timeupdate events (those sent while playing) |
| 2336 // "15 to 250ms", we choose the slowest frequency | 2389 // every "15 to 250ms", we choose the slowest frequency |
| 2337 static const double maxTimeupdateEventFrequency = 0.25; | 2390 static const double maxTimeupdateEventFrequency = 0.25; |
| 2338 | 2391 |
| 2339 void HTMLMediaElement::startPlaybackProgressTimer() { | 2392 void HTMLMediaElement::startPlaybackProgressTimer() { |
| 2340 if (m_playbackProgressTimer.isActive()) | 2393 if (m_playbackProgressTimer.isActive()) |
| 2341 return; | 2394 return; |
| 2342 | 2395 |
| 2343 m_previousProgressTime = WTF::currentTime(); | 2396 m_previousProgressTime = WTF::currentTime(); |
| 2344 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, | 2397 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, |
| 2345 BLINK_FROM_HERE); | 2398 BLINK_FROM_HERE); |
| 2346 } | 2399 } |
| 2347 | 2400 |
| 2348 void HTMLMediaElement::playbackProgressTimerFired(TimerBase*) { | 2401 void HTMLMediaElement::playbackProgressTimerFired(TimerBase*) { |
| 2349 if (!std::isnan(m_fragmentEndTime) && currentTime() >= m_fragmentEndTime && | 2402 if (!std::isnan(m_fragmentEndTime) && currentTime() >= m_fragmentEndTime && |
| 2350 getDirectionOfPlayback() == Forward) { | 2403 getDirectionOfPlayback() == Forward) { |
| 2351 m_fragmentEndTime = std::numeric_limits<double>::quiet_NaN(); | 2404 m_fragmentEndTime = std::numeric_limits<double>::quiet_NaN(); |
| 2352 if (!m_paused) { | 2405 if (!m_paused) { |
| 2353 UseCounter::count(document(), | 2406 UseCounter::count(document(), |
| 2354 UseCounter::HTMLMediaElementPauseAtFragmentEnd); | 2407 UseCounter::HTMLMediaElementPauseAtFragmentEnd); |
| 2355 // changes paused to true and fires a simple event named pause at the medi
a element. | 2408 // changes paused to true and fires a simple event named pause at the |
| 2409 // media element. |
| 2356 pauseInternal(); | 2410 pauseInternal(); |
| 2357 } | 2411 } |
| 2358 } | 2412 } |
| 2359 | 2413 |
| 2360 if (!m_seeking) | 2414 if (!m_seeking) |
| 2361 scheduleTimeupdateEvent(true); | 2415 scheduleTimeupdateEvent(true); |
| 2362 | 2416 |
| 2363 if (!playbackRate()) | 2417 if (!playbackRate()) |
| 2364 return; | 2418 return; |
| 2365 | 2419 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2511 BLINK_MEDIA_LOG << "removeVideoTrack(" << (void*)this << ")"; | 2565 BLINK_MEDIA_LOG << "removeVideoTrack(" << (void*)this << ")"; |
| 2512 | 2566 |
| 2513 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 2567 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
| 2514 return; | 2568 return; |
| 2515 | 2569 |
| 2516 videoTracks().remove(trackId); | 2570 videoTracks().remove(trackId); |
| 2517 } | 2571 } |
| 2518 | 2572 |
| 2519 void HTMLMediaElement::addTextTrack(WebInbandTextTrack* webTrack) { | 2573 void HTMLMediaElement::addTextTrack(WebInbandTextTrack* webTrack) { |
| 2520 // 4.8.10.12.2 Sourcing in-band text tracks | 2574 // 4.8.10.12.2 Sourcing in-band text tracks |
| 2521 // 1. Associate the relevant data with a new text track and its corresponding
new TextTrack object. | 2575 // 1. Associate the relevant data with a new text track and its corresponding |
| 2576 // new TextTrack object. |
| 2522 InbandTextTrack* textTrack = InbandTextTrack::create(webTrack); | 2577 InbandTextTrack* textTrack = InbandTextTrack::create(webTrack); |
| 2523 | 2578 |
| 2524 // 2. Set the new text track's kind, label, and language based on the semantic
s of the relevant data, | 2579 // 2. Set the new text track's kind, label, and language based on the |
| 2525 // as defined by the relevant specification. If there is no label in that data
, then the label must | 2580 // semantics of the relevant data, as defined by the relevant specification. |
| 2526 // be set to the empty string. | 2581 // If there is no label in that data, then the label must be set to the empty |
| 2527 // 3. Associate the text track list of cues with the rules for updating the te
xt track rendering appropriate | 2582 // string. |
| 2528 // for the format in question. | 2583 // 3. Associate the text track list of cues with the rules for updating the |
| 2529 // 4. If the new text track's kind is metadata, then set the text track in-ban
d metadata track dispatch type | 2584 // text track rendering appropriate for the format in question. |
| 2530 // as follows, based on the type of the media resource: | 2585 // 4. If the new text track's kind is metadata, then set the text track |
| 2531 // 5. Populate the new text track's list of cues with the cues parsed so far,
folllowing the guidelines for exposing | 2586 // in-band metadata track dispatch type as follows, based on the type of the |
| 2532 // cues, and begin updating it dynamically as necessary. | 2587 // media resource: |
| 2588 // 5. Populate the new text track's list of cues with the cues parsed so far, |
| 2589 // folllowing the guidelines for exposing cues, and begin updating it |
| 2590 // dynamically as necessary. |
| 2533 // - Thess are all done by the media engine. | 2591 // - Thess are all done by the media engine. |
| 2534 | 2592 |
| 2535 // 6. Set the new text track's readiness state to loaded. | 2593 // 6. Set the new text track's readiness state to loaded. |
| 2536 textTrack->setReadinessState(TextTrack::Loaded); | 2594 textTrack->setReadinessState(TextTrack::Loaded); |
| 2537 | 2595 |
| 2538 // 7. Set the new text track's mode to the mode consistent with the user's pre
ferences and the requirements of | 2596 // 7. Set the new text track's mode to the mode consistent with the user's |
| 2539 // the relevant specification for the data. | 2597 // preferences and the requirements of the relevant specification for the |
| 2598 // data. |
| 2540 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection() | 2599 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection() |
| 2541 scheduleTextTrackResourceLoad(); | 2600 scheduleTextTrackResourceLoad(); |
| 2542 | 2601 |
| 2543 // 8. Add the new text track to the media element's list of text tracks. | 2602 // 8. Add the new text track to the media element's list of text tracks. |
| 2544 // 9. Fire an event with the name addtrack, that does not bubble and is not ca
ncelable, and that uses the TrackEvent | 2603 // 9. Fire an event with the name addtrack, that does not bubble and is not |
| 2545 // interface, with the track attribute initialized to the text track's TextTra
ck object, at the media element's | 2604 // cancelable, and that uses the TrackEvent interface, with the track |
| 2546 // textTracks attribute's TextTrackList object. | 2605 // attribute initialized to the text track's TextTrack object, at the media |
| 2606 // element's textTracks attribute's TextTrackList object. |
| 2547 addTextTrack(textTrack); | 2607 addTextTrack(textTrack); |
| 2548 } | 2608 } |
| 2549 | 2609 |
| 2550 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) { | 2610 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) { |
| 2551 if (!m_textTracks) | 2611 if (!m_textTracks) |
| 2552 return; | 2612 return; |
| 2553 | 2613 |
| 2554 // This cast is safe because we created the InbandTextTrack with the WebInband
TextTrack | 2614 // This cast is safe because we created the InbandTextTrack with the |
| 2555 // passed to mediaPlayerDidAddTextTrack. | 2615 // WebInbandTextTrack passed to mediaPlayerDidAddTextTrack. |
| 2556 InbandTextTrack* textTrack = | 2616 InbandTextTrack* textTrack = |
| 2557 static_cast<InbandTextTrack*>(webTrack->client()); | 2617 static_cast<InbandTextTrack*>(webTrack->client()); |
| 2558 if (!textTrack) | 2618 if (!textTrack) |
| 2559 return; | 2619 return; |
| 2560 | 2620 |
| 2561 removeTextTrack(textTrack); | 2621 removeTextTrack(textTrack); |
| 2562 } | 2622 } |
| 2563 | 2623 |
| 2564 void HTMLMediaElement::textTracksChanged() { | 2624 void HTMLMediaElement::textTracksChanged() { |
| 2565 if (mediaControls()) | 2625 if (mediaControls()) |
| 2566 mediaControls()->refreshClosedCaptionsButtonVisibility(); | 2626 mediaControls()->refreshClosedCaptionsButtonVisibility(); |
| 2567 } | 2627 } |
| 2568 | 2628 |
| 2569 void HTMLMediaElement::addTextTrack(TextTrack* track) { | 2629 void HTMLMediaElement::addTextTrack(TextTrack* track) { |
| 2570 textTracks()->append(track); | 2630 textTracks()->append(track); |
| 2571 | 2631 |
| 2572 textTracksChanged(); | 2632 textTracksChanged(); |
| 2573 } | 2633 } |
| 2574 | 2634 |
| 2575 void HTMLMediaElement::removeTextTrack(TextTrack* track) { | 2635 void HTMLMediaElement::removeTextTrack(TextTrack* track) { |
| 2576 m_textTracks->remove(track); | 2636 m_textTracks->remove(track); |
| 2577 | 2637 |
| 2578 textTracksChanged(); | 2638 textTracksChanged(); |
| 2579 } | 2639 } |
| 2580 | 2640 |
| 2581 void HTMLMediaElement::forgetResourceSpecificTracks() { | 2641 void HTMLMediaElement::forgetResourceSpecificTracks() { |
| 2582 // Implements the "forget the media element's media-resource-specific tracks"
algorithm. | 2642 // Implements the "forget the media element's media-resource-specific tracks" |
| 2583 // The order is explicitly specified as text, then audio, and finally video. A
lso | 2643 // algorithm. The order is explicitly specified as text, then audio, and |
| 2584 // 'removetrack' events should not be fired. | 2644 // finally video. Also 'removetrack' events should not be fired. |
| 2585 if (m_textTracks) { | 2645 if (m_textTracks) { |
| 2586 TrackDisplayUpdateScope scope(this->cueTimeline()); | 2646 TrackDisplayUpdateScope scope(this->cueTimeline()); |
| 2587 m_textTracks->removeAllInbandTracks(); | 2647 m_textTracks->removeAllInbandTracks(); |
| 2588 textTracksChanged(); | 2648 textTracksChanged(); |
| 2589 } | 2649 } |
| 2590 | 2650 |
| 2591 m_audioTracks->removeAll(); | 2651 m_audioTracks->removeAll(); |
| 2592 m_videoTracks->removeAll(); | 2652 m_videoTracks->removeAll(); |
| 2593 | 2653 |
| 2594 m_audioTracksTimer.stop(); | 2654 m_audioTracksTimer.stop(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 | 2695 |
| 2636 TextTrackList* HTMLMediaElement::textTracks() { | 2696 TextTrackList* HTMLMediaElement::textTracks() { |
| 2637 if (!m_textTracks) | 2697 if (!m_textTracks) |
| 2638 m_textTracks = TextTrackList::create(this); | 2698 m_textTracks = TextTrackList::create(this); |
| 2639 | 2699 |
| 2640 return m_textTracks.get(); | 2700 return m_textTracks.get(); |
| 2641 } | 2701 } |
| 2642 | 2702 |
| 2643 void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement) { | 2703 void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement) { |
| 2644 // 4.8.10.12.3 Sourcing out-of-band text tracks | 2704 // 4.8.10.12.3 Sourcing out-of-band text tracks |
| 2645 // When a track element's parent element changes and the new parent is a media
element, | 2705 // When a track element's parent element changes and the new parent is a media |
| 2646 // then the user agent must add the track element's corresponding text track t
o the | 2706 // element, then the user agent must add the track element's corresponding |
| 2647 // media element's list of text tracks ... [continues in TextTrackList::append
] | 2707 // text track to the media element's list of text tracks ... [continues in |
| 2708 // TextTrackList::append] |
| 2648 TextTrack* textTrack = trackElement->track(); | 2709 TextTrack* textTrack = trackElement->track(); |
| 2649 if (!textTrack) | 2710 if (!textTrack) |
| 2650 return; | 2711 return; |
| 2651 | 2712 |
| 2652 addTextTrack(textTrack); | 2713 addTextTrack(textTrack); |
| 2653 | 2714 |
| 2654 // Do not schedule the track loading until parsing finishes so we don't start
before all tracks | 2715 // Do not schedule the track loading until parsing finishes so we don't start |
| 2655 // in the markup have been added. | 2716 // before all tracks in the markup have been added. |
| 2656 if (isFinishedParsingChildren()) | 2717 if (isFinishedParsingChildren()) |
| 2657 scheduleTextTrackResourceLoad(); | 2718 scheduleTextTrackResourceLoad(); |
| 2658 } | 2719 } |
| 2659 | 2720 |
| 2660 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) { | 2721 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) { |
| 2661 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); | 2722 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); |
| 2662 BLINK_MEDIA_LOG << "didRemoveTrackElement(" << (void*)this << ") - 'src' is " | 2723 BLINK_MEDIA_LOG << "didRemoveTrackElement(" << (void*)this << ") - 'src' is " |
| 2663 << urlForLoggingMedia(url); | 2724 << urlForLoggingMedia(url); |
| 2664 | 2725 |
| 2665 TextTrack* textTrack = trackElement->track(); | 2726 TextTrack* textTrack = trackElement->track(); |
| 2666 if (!textTrack) | 2727 if (!textTrack) |
| 2667 return; | 2728 return; |
| 2668 | 2729 |
| 2669 textTrack->setHasBeenConfigured(false); | 2730 textTrack->setHasBeenConfigured(false); |
| 2670 | 2731 |
| 2671 if (!m_textTracks) | 2732 if (!m_textTracks) |
| 2672 return; | 2733 return; |
| 2673 | 2734 |
| 2674 // 4.8.10.12.3 Sourcing out-of-band text tracks | 2735 // 4.8.10.12.3 Sourcing out-of-band text tracks |
| 2675 // When a track element's parent element changes and the old parent was a medi
a element, | 2736 // When a track element's parent element changes and the old parent was a |
| 2676 // then the user agent must remove the track element's corresponding text trac
k from the | 2737 // media element, then the user agent must remove the track element's |
| 2677 // media element's list of text tracks. | 2738 // corresponding text track from the media element's list of text tracks. |
| 2678 removeTextTrack(textTrack); | 2739 removeTextTrack(textTrack); |
| 2679 | 2740 |
| 2680 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack); | 2741 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack); |
| 2681 if (index != kNotFound) | 2742 if (index != kNotFound) |
| 2682 m_textTracksWhenResourceSelectionBegan.remove(index); | 2743 m_textTracksWhenResourceSelectionBegan.remove(index); |
| 2683 } | 2744 } |
| 2684 | 2745 |
| 2685 void HTMLMediaElement::honorUserPreferencesForAutomaticTextTrackSelection() { | 2746 void HTMLMediaElement::honorUserPreferencesForAutomaticTextTrackSelection() { |
| 2686 if (!m_textTracks || !m_textTracks->length()) | 2747 if (!m_textTracks || !m_textTracks->length()) |
| 2687 return; | 2748 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2700 configuration.textTrackKindUserPreference = | 2761 configuration.textTrackKindUserPreference = |
| 2701 settings->textTrackKindUserPreference(); | 2762 settings->textTrackKindUserPreference(); |
| 2702 | 2763 |
| 2703 AutomaticTrackSelection trackSelection(configuration); | 2764 AutomaticTrackSelection trackSelection(configuration); |
| 2704 trackSelection.perform(*m_textTracks); | 2765 trackSelection.perform(*m_textTracks); |
| 2705 | 2766 |
| 2706 textTracksChanged(); | 2767 textTracksChanged(); |
| 2707 } | 2768 } |
| 2708 | 2769 |
| 2709 bool HTMLMediaElement::havePotentialSourceChild() { | 2770 bool HTMLMediaElement::havePotentialSourceChild() { |
| 2710 // Stash the current <source> node and next nodes so we can restore them after
checking | 2771 // Stash the current <source> node and next nodes so we can restore them after |
| 2711 // to see there is another potential. | 2772 // checking to see there is another potential. |
| 2712 HTMLSourceElement* currentSourceNode = m_currentSourceNode; | 2773 HTMLSourceElement* currentSourceNode = m_currentSourceNode; |
| 2713 Node* nextNode = m_nextChildNodeToConsider; | 2774 Node* nextNode = m_nextChildNodeToConsider; |
| 2714 | 2775 |
| 2715 KURL nextURL = selectNextSourceChild(0, DoNothing); | 2776 KURL nextURL = selectNextSourceChild(0, DoNothing); |
| 2716 | 2777 |
| 2717 m_currentSourceNode = currentSourceNode; | 2778 m_currentSourceNode = currentSourceNode; |
| 2718 m_nextChildNodeToConsider = nextNode; | 2779 m_nextChildNodeToConsider = nextNode; |
| 2719 | 2780 |
| 2720 return nextURL.isValid(); | 2781 return nextURL.isValid(); |
| 2721 } | 2782 } |
| 2722 | 2783 |
| 2723 KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, | 2784 KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, |
| 2724 InvalidURLAction actionIfInvalid) { | 2785 InvalidURLAction actionIfInvalid) { |
| 2725 // Don't log if this was just called to find out if there are any valid <sourc
e> elements. | 2786 // Don't log if this was just called to find out if there are any valid |
| 2787 // <source> elements. |
| 2726 bool shouldLog = actionIfInvalid != DoNothing; | 2788 bool shouldLog = actionIfInvalid != DoNothing; |
| 2727 if (shouldLog) | 2789 if (shouldLog) |
| 2728 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; | 2790 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; |
| 2729 | 2791 |
| 2730 if (!m_nextChildNodeToConsider) { | 2792 if (!m_nextChildNodeToConsider) { |
| 2731 if (shouldLog) | 2793 if (shouldLog) |
| 2732 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this | 2794 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this |
| 2733 << ") -> 0x0000, \"\""; | 2795 << ") -> 0x0000, \"\""; |
| 2734 return KURL(); | 2796 return KURL(); |
| 2735 } | 2797 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2819 return canUseSourceElement ? mediaURL : KURL(); | 2881 return canUseSourceElement ? mediaURL : KURL(); |
| 2820 } | 2882 } |
| 2821 | 2883 |
| 2822 void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source) { | 2884 void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source) { |
| 2823 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ", " << source << ")"; | 2885 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ", " << source << ")"; |
| 2824 | 2886 |
| 2825 KURL url = source->getNonEmptyURLAttribute(srcAttr); | 2887 KURL url = source->getNonEmptyURLAttribute(srcAttr); |
| 2826 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ") - 'src' is " | 2888 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this << ") - 'src' is " |
| 2827 << urlForLoggingMedia(url); | 2889 << urlForLoggingMedia(url); |
| 2828 | 2890 |
| 2829 // We should only consider a <source> element when there is not src attribute
at all. | 2891 // We should only consider a <source> element when there is not src attribute |
| 2892 // at all. |
| 2830 if (fastHasAttribute(srcAttr)) | 2893 if (fastHasAttribute(srcAttr)) |
| 2831 return; | 2894 return; |
| 2832 | 2895 |
| 2833 // 4.8.8 - If a source element is inserted as a child of a media element that
has no src | 2896 // 4.8.8 - If a source element is inserted as a child of a media element that |
| 2834 // attribute and whose networkState has the value NETWORK_EMPTY, the user agen
t must invoke | 2897 // has no src attribute and whose networkState has the value NETWORK_EMPTY, |
| 2835 // the media element's resource selection algorithm. | 2898 // the user agent must invoke the media element's resource selection |
| 2899 // algorithm. |
| 2836 if (getNetworkState() == HTMLMediaElement::kNetworkEmpty) { | 2900 if (getNetworkState() == HTMLMediaElement::kNetworkEmpty) { |
| 2837 invokeResourceSelectionAlgorithm(); | 2901 invokeResourceSelectionAlgorithm(); |
| 2838 // Ignore current |m_nextChildNodeToConsider| and consider |source|. | 2902 // Ignore current |m_nextChildNodeToConsider| and consider |source|. |
| 2839 m_nextChildNodeToConsider = source; | 2903 m_nextChildNodeToConsider = source; |
| 2840 return; | 2904 return; |
| 2841 } | 2905 } |
| 2842 | 2906 |
| 2843 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { | 2907 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { |
| 2844 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this | 2908 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this |
| 2845 << ") - <source> inserted immediately after current source"; | 2909 << ") - <source> inserted immediately after current source"; |
| 2846 // Ignore current |m_nextChildNodeToConsider| and consider |source|. | 2910 // Ignore current |m_nextChildNodeToConsider| and consider |source|. |
| 2847 m_nextChildNodeToConsider = source; | 2911 m_nextChildNodeToConsider = source; |
| 2848 return; | 2912 return; |
| 2849 } | 2913 } |
| 2850 | 2914 |
| 2851 // Consider current |m_nextChildNodeToConsider| as it is already in the middle
of processing. | 2915 // Consider current |m_nextChildNodeToConsider| as it is already in the middle |
| 2916 // of processing. |
| 2852 if (m_nextChildNodeToConsider) | 2917 if (m_nextChildNodeToConsider) |
| 2853 return; | 2918 return; |
| 2854 | 2919 |
| 2855 if (m_loadState != WaitingForSource) | 2920 if (m_loadState != WaitingForSource) |
| 2856 return; | 2921 return; |
| 2857 | 2922 |
| 2858 // 4.8.9.5, resource selection algorithm, source elements section: | 2923 // 4.8.9.5, resource selection algorithm, source elements section: |
| 2859 // 21. Wait until the node after pointer is a node other than the end of the l
ist. (This step might wait forever.) | 2924 // 21. Wait until the node after pointer is a node other than the end of the |
| 2925 // list. (This step might wait forever.) |
| 2860 // 22. Asynchronously await a stable state... | 2926 // 22. Asynchronously await a stable state... |
| 2861 // 23. Set the element's delaying-the-load-event flag back to true (this delay
s the load event again, in case | 2927 // 23. Set the element's delaying-the-load-event flag back to true (this |
| 2862 // it hasn't been fired yet). | 2928 // delays the load event again, in case it hasn't been fired yet). |
| 2863 setShouldDelayLoadEvent(true); | 2929 setShouldDelayLoadEvent(true); |
| 2864 | 2930 |
| 2865 // 24. Set the networkState back to NETWORK_LOADING. | 2931 // 24. Set the networkState back to NETWORK_LOADING. |
| 2866 setNetworkState(kNetworkLoading); | 2932 setNetworkState(kNetworkLoading); |
| 2867 | 2933 |
| 2868 // 25. Jump back to the find next candidate step above. | 2934 // 25. Jump back to the find next candidate step above. |
| 2869 m_nextChildNodeToConsider = source; | 2935 m_nextChildNodeToConsider = source; |
| 2870 scheduleNextSourceChild(); | 2936 scheduleNextSourceChild(); |
| 2871 } | 2937 } |
| 2872 | 2938 |
| 2873 void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source) { | 2939 void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source) { |
| 2874 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ", " << source | 2940 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ", " << source |
| 2875 << ")"; | 2941 << ")"; |
| 2876 | 2942 |
| 2877 KURL url = source->getNonEmptyURLAttribute(srcAttr); | 2943 KURL url = source->getNonEmptyURLAttribute(srcAttr); |
| 2878 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ") - 'src' is " | 2944 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ") - 'src' is " |
| 2879 << urlForLoggingMedia(url); | 2945 << urlForLoggingMedia(url); |
| 2880 | 2946 |
| 2881 if (source != m_currentSourceNode && source != m_nextChildNodeToConsider) | 2947 if (source != m_currentSourceNode && source != m_nextChildNodeToConsider) |
| 2882 return; | 2948 return; |
| 2883 | 2949 |
| 2884 if (source == m_nextChildNodeToConsider) { | 2950 if (source == m_nextChildNodeToConsider) { |
| 2885 if (m_currentSourceNode) | 2951 if (m_currentSourceNode) |
| 2886 m_nextChildNodeToConsider = m_currentSourceNode->nextSibling(); | 2952 m_nextChildNodeToConsider = m_currentSourceNode->nextSibling(); |
| 2887 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this | 2953 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this |
| 2888 << ") - m_nextChildNodeToConsider set to " | 2954 << ") - m_nextChildNodeToConsider set to " |
| 2889 << m_nextChildNodeToConsider.get(); | 2955 << m_nextChildNodeToConsider.get(); |
| 2890 } else if (source == m_currentSourceNode) { | 2956 } else if (source == m_currentSourceNode) { |
| 2891 // Clear the current source node pointer, but don't change the movie as the
spec says: | 2957 // Clear the current source node pointer, but don't change the movie as the |
| 2892 // 4.8.8 - Dynamically modifying a source element and its attribute when the
element is already | 2958 // spec says: |
| 2893 // inserted in a video or audio element will have no effect. | 2959 // 4.8.8 - Dynamically modifying a source element and its attribute when the |
| 2960 // element is already inserted in a video or audio element will have no |
| 2961 // effect. |
| 2894 m_currentSourceNode = nullptr; | 2962 m_currentSourceNode = nullptr; |
| 2895 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this | 2963 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this |
| 2896 << ") - m_currentSourceNode set to 0"; | 2964 << ") - m_currentSourceNode set to 0"; |
| 2897 } | 2965 } |
| 2898 } | 2966 } |
| 2899 | 2967 |
| 2900 void HTMLMediaElement::timeChanged() { | 2968 void HTMLMediaElement::timeChanged() { |
| 2901 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; | 2969 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; |
| 2902 | 2970 |
| 2903 cueTimeline().updateActiveCues(currentTime()); | 2971 cueTimeline().updateActiveCues(currentTime()); |
| 2904 | 2972 |
| 2905 invalidateCachedTime(); | 2973 invalidateCachedTime(); |
| 2906 | 2974 |
| 2907 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with the
seek. | 2975 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with the |
| 2976 // seek. |
| 2908 if (m_seeking && m_readyState >= kHaveCurrentData && | 2977 if (m_seeking && m_readyState >= kHaveCurrentData && |
| 2909 !webMediaPlayer()->seeking()) | 2978 !webMediaPlayer()->seeking()) |
| 2910 finishSeek(); | 2979 finishSeek(); |
| 2911 | 2980 |
| 2912 // Always call scheduleTimeupdateEvent when the media engine reports a time di
scontinuity, | 2981 // Always call scheduleTimeupdateEvent when the media engine reports a time |
| 2913 // it will only queue a 'timeupdate' event if we haven't already posted one at
the current | 2982 // discontinuity, it will only queue a 'timeupdate' event if we haven't |
| 2914 // movie time. | 2983 // already posted one at the current movie time. |
| 2915 scheduleTimeupdateEvent(false); | 2984 scheduleTimeupdateEvent(false); |
| 2916 | 2985 |
| 2917 double now = currentTime(); | 2986 double now = currentTime(); |
| 2918 double dur = duration(); | 2987 double dur = duration(); |
| 2919 | 2988 |
| 2920 // When the current playback position reaches the end of the media resource wh
en the direction of | 2989 // When the current playback position reaches the end of the media resource |
| 2921 // playback is forwards, then the user agent must follow these steps: | 2990 // when the direction of playback is forwards, then the user agent must follow |
| 2991 // these steps: |
| 2922 if (!std::isnan(dur) && dur && now >= dur && | 2992 if (!std::isnan(dur) && dur && now >= dur && |
| 2923 getDirectionOfPlayback() == Forward) { | 2993 getDirectionOfPlayback() == Forward) { |
| 2924 // If the media element has a loop attribute specified | 2994 // If the media element has a loop attribute specified |
| 2925 if (loop()) { | 2995 if (loop()) { |
| 2926 // then seek to the earliest possible position of the media resource and
abort these steps. | 2996 // then seek to the earliest possible position of the media resource and |
| 2997 // abort these steps. |
| 2927 seek(0); | 2998 seek(0); |
| 2928 } else { | 2999 } else { |
| 2929 // If the media element has still ended playback, and the direction of pla
yback is still | 3000 // If the media element has still ended playback, and the direction of |
| 2930 // forwards, and paused is false, | 3001 // playback is still forwards, and paused is false, |
| 2931 if (!m_paused) { | 3002 if (!m_paused) { |
| 2932 // changes paused to true and fires a simple event named pause at the me
dia element. | 3003 // changes paused to true and fires a simple event named pause at the |
| 3004 // media element. |
| 2933 m_paused = true; | 3005 m_paused = true; |
| 2934 scheduleEvent(EventTypeNames::pause); | 3006 scheduleEvent(EventTypeNames::pause); |
| 2935 scheduleRejectPlayPromises(AbortError); | 3007 scheduleRejectPlayPromises(AbortError); |
| 2936 } | 3008 } |
| 2937 // Queue a task to fire a simple event named ended at the media element. | 3009 // Queue a task to fire a simple event named ended at the media element. |
| 2938 scheduleEvent(EventTypeNames::ended); | 3010 scheduleEvent(EventTypeNames::ended); |
| 2939 } | 3011 } |
| 2940 } | 3012 } |
| 2941 updatePlayState(); | 3013 updatePlayState(); |
| 2942 } | 3014 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3075 if (!webMediaPlayer()) | 3147 if (!webMediaPlayer()) |
| 3076 return TimeRanges::create(); | 3148 return TimeRanges::create(); |
| 3077 | 3149 |
| 3078 if (m_mediaSource) | 3150 if (m_mediaSource) |
| 3079 return m_mediaSource->seekable(); | 3151 return m_mediaSource->seekable(); |
| 3080 | 3152 |
| 3081 return TimeRanges::create(webMediaPlayer()->seekable()); | 3153 return TimeRanges::create(webMediaPlayer()->seekable()); |
| 3082 } | 3154 } |
| 3083 | 3155 |
| 3084 bool HTMLMediaElement::potentiallyPlaying() const { | 3156 bool HTMLMediaElement::potentiallyPlaying() const { |
| 3085 // "pausedToBuffer" means the media engine's rate is 0, but only because it ha
d to stop playing | 3157 // "pausedToBuffer" means the media engine's rate is 0, but only because it |
| 3086 // when it ran out of buffered data. A movie in this state is "potentially pla
ying", modulo the | 3158 // had to stop playing when it ran out of buffered data. A movie in this state |
| 3087 // checks in couldPlayIfEnoughData(). | 3159 // is "potentially playing", modulo the checks in couldPlayIfEnoughData(). |
| 3088 bool pausedToBuffer = | 3160 bool pausedToBuffer = |
| 3089 m_readyStateMaximum >= kHaveFutureData && m_readyState < kHaveFutureData; | 3161 m_readyStateMaximum >= kHaveFutureData && m_readyState < kHaveFutureData; |
| 3090 return (pausedToBuffer || m_readyState >= kHaveFutureData) && | 3162 return (pausedToBuffer || m_readyState >= kHaveFutureData) && |
| 3091 couldPlayIfEnoughData(); | 3163 couldPlayIfEnoughData(); |
| 3092 } | 3164 } |
| 3093 | 3165 |
| 3094 bool HTMLMediaElement::couldPlayIfEnoughData() const { | 3166 bool HTMLMediaElement::couldPlayIfEnoughData() const { |
| 3095 return !paused() && !endedPlayback() && !stoppedDueToErrors(); | 3167 return !paused() && !endedPlayback() && !stoppedDueToErrors(); |
| 3096 } | 3168 } |
| 3097 | 3169 |
| 3098 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const { | 3170 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const { |
| 3099 double dur = duration(); | 3171 double dur = duration(); |
| 3100 if (std::isnan(dur)) | 3172 if (std::isnan(dur)) |
| 3101 return false; | 3173 return false; |
| 3102 | 3174 |
| 3103 // 4.8.10.8 Playing the media resource | 3175 // 4.8.10.8 Playing the media resource |
| 3104 | 3176 |
| 3105 // A media element is said to have ended playback when the element's | 3177 // A media element is said to have ended playback when the element's |
| 3106 // readyState attribute is HAVE_METADATA or greater, | 3178 // readyState attribute is HAVE_METADATA or greater, |
| 3107 if (m_readyState < kHaveMetadata) | 3179 if (m_readyState < kHaveMetadata) |
| 3108 return false; | 3180 return false; |
| 3109 | 3181 |
| 3110 // and the current playback position is the end of the media resource and the
direction | 3182 // and the current playback position is the end of the media resource and the |
| 3111 // of playback is forwards, Either the media element does not have a loop attr
ibute specified, | 3183 // direction of playback is forwards, Either the media element does not have a |
| 3184 // loop attribute specified, |
| 3112 double now = currentTime(); | 3185 double now = currentTime(); |
| 3113 if (getDirectionOfPlayback() == Forward) | 3186 if (getDirectionOfPlayback() == Forward) |
| 3114 return dur > 0 && now >= dur && | 3187 return dur > 0 && now >= dur && |
| 3115 (loopCondition == LoopCondition::Ignored || !loop()); | 3188 (loopCondition == LoopCondition::Ignored || !loop()); |
| 3116 | 3189 |
| 3117 // or the current playback position is the earliest possible position and the
direction | 3190 // or the current playback position is the earliest possible position and the |
| 3118 // of playback is backwards | 3191 // direction of playback is backwards |
| 3119 DCHECK_EQ(getDirectionOfPlayback(), Backward); | 3192 DCHECK_EQ(getDirectionOfPlayback(), Backward); |
| 3120 return now <= 0; | 3193 return now <= 0; |
| 3121 } | 3194 } |
| 3122 | 3195 |
| 3123 bool HTMLMediaElement::stoppedDueToErrors() const { | 3196 bool HTMLMediaElement::stoppedDueToErrors() const { |
| 3124 if (m_readyState >= kHaveMetadata && m_error) { | 3197 if (m_readyState >= kHaveMetadata && m_error) { |
| 3125 TimeRanges* seekableRanges = seekable(); | 3198 TimeRanges* seekableRanges = seekable(); |
| 3126 if (!seekableRanges->contain(currentTime())) | 3199 if (!seekableRanges->contain(currentTime())) |
| 3127 return true; | 3200 return true; |
| 3128 } | 3201 } |
| 3129 | 3202 |
| 3130 return false; | 3203 return false; |
| 3131 } | 3204 } |
| 3132 | 3205 |
| 3133 void HTMLMediaElement::updatePlayState() { | 3206 void HTMLMediaElement::updatePlayState() { |
| 3134 bool isPlaying = webMediaPlayer() && !webMediaPlayer()->paused(); | 3207 bool isPlaying = webMediaPlayer() && !webMediaPlayer()->paused(); |
| 3135 bool shouldBePlaying = potentiallyPlaying(); | 3208 bool shouldBePlaying = potentiallyPlaying(); |
| 3136 | 3209 |
| 3137 BLINK_MEDIA_LOG << "updatePlayState(" << (void*)this | 3210 BLINK_MEDIA_LOG << "updatePlayState(" << (void*)this |
| 3138 << ") - shouldBePlaying = " << boolString(shouldBePlaying) | 3211 << ") - shouldBePlaying = " << boolString(shouldBePlaying) |
| 3139 << ", isPlaying = " << boolString(isPlaying); | 3212 << ", isPlaying = " << boolString(isPlaying); |
| 3140 | 3213 |
| 3141 if (shouldBePlaying) { | 3214 if (shouldBePlaying) { |
| 3142 setDisplayMode(Video); | 3215 setDisplayMode(Video); |
| 3143 invalidateCachedTime(); | 3216 invalidateCachedTime(); |
| 3144 | 3217 |
| 3145 if (!isPlaying) { | 3218 if (!isPlaying) { |
| 3146 // Set rate, muted before calling play in case they were set before the me
dia engine was setup. | 3219 // Set rate, muted before calling play in case they were set before the |
| 3147 // The media engine should just stash the rate and muted values since it i
sn't already playing. | 3220 // media engine was setup. The media engine should just stash the rate |
| 3221 // and muted values since it isn't already playing. |
| 3148 webMediaPlayer()->setRate(playbackRate()); | 3222 webMediaPlayer()->setRate(playbackRate()); |
| 3149 updateVolume(); | 3223 updateVolume(); |
| 3150 webMediaPlayer()->play(); | 3224 webMediaPlayer()->play(); |
| 3151 m_autoplayHelper->playbackStarted(); | 3225 m_autoplayHelper->playbackStarted(); |
| 3152 } | 3226 } |
| 3153 | 3227 |
| 3154 if (mediaControls()) | 3228 if (mediaControls()) |
| 3155 mediaControls()->playbackStarted(); | 3229 mediaControls()->playbackStarted(); |
| 3156 startPlaybackProgressTimer(); | 3230 startPlaybackProgressTimer(); |
| 3157 m_playing = true; | 3231 m_playing = true; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3238 cueTimeline().updateActiveCues(0); | 3312 cueTimeline().updateActiveCues(0); |
| 3239 m_playing = false; | 3313 m_playing = false; |
| 3240 m_paused = true; | 3314 m_paused = true; |
| 3241 m_seeking = false; | 3315 m_seeking = false; |
| 3242 | 3316 |
| 3243 if (layoutObject()) | 3317 if (layoutObject()) |
| 3244 layoutObject()->updateFromElement(); | 3318 layoutObject()->updateFromElement(); |
| 3245 | 3319 |
| 3246 stopPeriodicTimers(); | 3320 stopPeriodicTimers(); |
| 3247 | 3321 |
| 3248 // Ensure that hasPendingActivity() is not preventing garbage collection, sinc
e otherwise this | 3322 // Ensure that hasPendingActivity() is not preventing garbage collection, |
| 3249 // media element will simply leak. | 3323 // since otherwise this media element will simply leak. |
| 3250 DCHECK(!hasPendingActivity()); | 3324 DCHECK(!hasPendingActivity()); |
| 3251 } | 3325 } |
| 3252 | 3326 |
| 3253 bool HTMLMediaElement::hasPendingActivity() const { | 3327 bool HTMLMediaElement::hasPendingActivity() const { |
| 3254 // The delaying-the-load-event flag is set by resource selection algorithm whe
n looking for a | 3328 // The delaying-the-load-event flag is set by resource selection algorithm |
| 3255 // resource to load, before networkState has reached to kNetworkLoading. | 3329 // when looking for a resource to load, before networkState has reached to |
| 3330 // kNetworkLoading. |
| 3256 if (m_shouldDelayLoadEvent) | 3331 if (m_shouldDelayLoadEvent) |
| 3257 return true; | 3332 return true; |
| 3258 | 3333 |
| 3259 // When networkState is kNetworkLoading, progress and stalled events may be fi
red. | 3334 // When networkState is kNetworkLoading, progress and stalled events may be |
| 3335 // fired. |
| 3260 if (m_networkState == kNetworkLoading) | 3336 if (m_networkState == kNetworkLoading) |
| 3261 return true; | 3337 return true; |
| 3262 | 3338 |
| 3263 // When playing or if playback may continue, timeupdate events may be fired. | 3339 // When playing or if playback may continue, timeupdate events may be fired. |
| 3264 if (couldPlayIfEnoughData()) | 3340 if (couldPlayIfEnoughData()) |
| 3265 return true; | 3341 return true; |
| 3266 | 3342 |
| 3267 // When the seek finishes timeupdate and seeked events will be fired. | 3343 // When the seek finishes timeupdate and seeked events will be fired. |
| 3268 if (m_seeking) | 3344 if (m_seeking) |
| 3269 return true; | 3345 return true; |
| 3270 | 3346 |
| 3271 // When connected to a MediaSource, e.g. setting MediaSource.duration will cau
se a | 3347 // When connected to a MediaSource, e.g. setting MediaSource.duration will |
| 3272 // durationchange event to be fired. | 3348 // cause a durationchange event to be fired. |
| 3273 if (m_mediaSource) | 3349 if (m_mediaSource) |
| 3274 return true; | 3350 return true; |
| 3275 | 3351 |
| 3276 // Wait for any pending events to be fired. | 3352 // Wait for any pending events to be fired. |
| 3277 if (m_asyncEventQueue->hasPendingEvents()) | 3353 if (m_asyncEventQueue->hasPendingEvents()) |
| 3278 return true; | 3354 return true; |
| 3279 | 3355 |
| 3280 return false; | 3356 return false; |
| 3281 } | 3357 } |
| 3282 | 3358 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3409 if (!m_textTracks || !m_textTracks->length()) | 3485 if (!m_textTracks || !m_textTracks->length()) |
| 3410 return; | 3486 return; |
| 3411 | 3487 |
| 3412 markCaptionAndSubtitleTracksAsUnconfigured(); | 3488 markCaptionAndSubtitleTracksAsUnconfigured(); |
| 3413 m_processingPreferenceChange = true; | 3489 m_processingPreferenceChange = true; |
| 3414 m_textTracksVisible = false; | 3490 m_textTracksVisible = false; |
| 3415 honorUserPreferencesForAutomaticTextTrackSelection(); | 3491 honorUserPreferencesForAutomaticTextTrackSelection(); |
| 3416 m_processingPreferenceChange = false; | 3492 m_processingPreferenceChange = false; |
| 3417 | 3493 |
| 3418 // If a track is set to 'showing' post performing automatic track selection, | 3494 // If a track is set to 'showing' post performing automatic track selection, |
| 3419 // set text tracks state to visible to update the CC button and display the tr
ack. | 3495 // set text tracks state to visible to update the CC button and display the |
| 3496 // track. |
| 3420 m_textTracksVisible = m_textTracks->hasShowingTracks(); | 3497 m_textTracksVisible = m_textTracks->hasShowingTracks(); |
| 3421 updateTextTrackDisplay(); | 3498 updateTextTrackDisplay(); |
| 3422 } | 3499 } |
| 3423 | 3500 |
| 3424 void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured() { | 3501 void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured() { |
| 3425 if (!m_textTracks) | 3502 if (!m_textTracks) |
| 3426 return; | 3503 return; |
| 3427 | 3504 |
| 3428 // Mark all tracks as not "configured" so that | 3505 // Mark all tracks as not "configured" so that |
| 3429 // honorUserPreferencesForAutomaticTextTrackSelection() will reconsider | 3506 // honorUserPreferencesForAutomaticTextTrackSelection() will reconsider |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3595 return WebMediaPlayer::CORSModeUnspecified; | 3672 return WebMediaPlayer::CORSModeUnspecified; |
| 3596 if (equalIgnoringCase(crossOriginMode, "use-credentials")) | 3673 if (equalIgnoringCase(crossOriginMode, "use-credentials")) |
| 3597 return WebMediaPlayer::CORSModeUseCredentials; | 3674 return WebMediaPlayer::CORSModeUseCredentials; |
| 3598 return WebMediaPlayer::CORSModeAnonymous; | 3675 return WebMediaPlayer::CORSModeAnonymous; |
| 3599 } | 3676 } |
| 3600 | 3677 |
| 3601 void HTMLMediaElement::setWebLayer(WebLayer* webLayer) { | 3678 void HTMLMediaElement::setWebLayer(WebLayer* webLayer) { |
| 3602 if (webLayer == m_webLayer) | 3679 if (webLayer == m_webLayer) |
| 3603 return; | 3680 return; |
| 3604 | 3681 |
| 3605 // If either of the layers is null we need to enable or disable compositing. T
his is done by triggering a style recalc. | 3682 // If either of the layers is null we need to enable or disable compositing. |
| 3683 // This is done by triggering a style recalc. |
| 3606 if (!m_webLayer || !webLayer) | 3684 if (!m_webLayer || !webLayer) |
| 3607 setNeedsCompositingUpdate(); | 3685 setNeedsCompositingUpdate(); |
| 3608 | 3686 |
| 3609 if (m_webLayer) | 3687 if (m_webLayer) |
| 3610 GraphicsLayer::unregisterContentsLayer(m_webLayer); | 3688 GraphicsLayer::unregisterContentsLayer(m_webLayer); |
| 3611 m_webLayer = webLayer; | 3689 m_webLayer = webLayer; |
| 3612 if (m_webLayer) | 3690 if (m_webLayer) |
| 3613 GraphicsLayer::registerContentsLayer(m_webLayer); | 3691 GraphicsLayer::registerContentsLayer(m_webLayer); |
| 3614 } | 3692 } |
| 3615 | 3693 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3663 visitor->traceWrappers(m_videoTracks); | 3741 visitor->traceWrappers(m_videoTracks); |
| 3664 visitor->traceWrappers(m_audioTracks); | 3742 visitor->traceWrappers(m_audioTracks); |
| 3665 visitor->traceWrappers(m_textTracks); | 3743 visitor->traceWrappers(m_textTracks); |
| 3666 HTMLElement::traceWrappers(visitor); | 3744 HTMLElement::traceWrappers(visitor); |
| 3667 } | 3745 } |
| 3668 | 3746 |
| 3669 void HTMLMediaElement::createPlaceholderTracksIfNecessary() { | 3747 void HTMLMediaElement::createPlaceholderTracksIfNecessary() { |
| 3670 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 3748 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
| 3671 return; | 3749 return; |
| 3672 | 3750 |
| 3673 // Create a placeholder audio track if the player says it has audio but it did
n't explicitly announce the tracks. | 3751 // Create a placeholder audio track if the player says it has audio but it |
| 3752 // didn't explicitly announce the tracks. |
| 3674 if (hasAudio() && !audioTracks().length()) | 3753 if (hasAudio() && !audioTracks().length()) |
| 3675 addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, | 3754 addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, |
| 3676 "Audio Track", "", true); | 3755 "Audio Track", "", true); |
| 3677 | 3756 |
| 3678 // Create a placeholder video track if the player says it has video but it did
n't explicitly announce the tracks. | 3757 // Create a placeholder video track if the player says it has video but it |
| 3758 // didn't explicitly announce the tracks. |
| 3679 if (hasVideo() && !videoTracks().length()) | 3759 if (hasVideo() && !videoTracks().length()) |
| 3680 addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, | 3760 addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, |
| 3681 "Video Track", "", true); | 3761 "Video Track", "", true); |
| 3682 } | 3762 } |
| 3683 | 3763 |
| 3684 void HTMLMediaElement::selectInitialTracksIfNecessary() { | 3764 void HTMLMediaElement::selectInitialTracksIfNecessary() { |
| 3685 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 3765 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
| 3686 return; | 3766 return; |
| 3687 | 3767 |
| 3688 // Enable the first audio track if an audio track hasn't been enabled yet. | 3768 // Enable the first audio track if an audio track hasn't been enabled yet. |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3874 if (shouldAutoplay()) { | 3954 if (shouldAutoplay()) { |
| 3875 m_paused = false; | 3955 m_paused = false; |
| 3876 invalidateCachedTime(); | 3956 invalidateCachedTime(); |
| 3877 scheduleEvent(EventTypeNames::play); | 3957 scheduleEvent(EventTypeNames::play); |
| 3878 scheduleNotifyPlaying(); | 3958 scheduleNotifyPlaying(); |
| 3879 m_autoplaying = false; | 3959 m_autoplaying = false; |
| 3880 | 3960 |
| 3881 updatePlayState(); | 3961 updatePlayState(); |
| 3882 } | 3962 } |
| 3883 | 3963 |
| 3884 // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay()
is never called. | 3964 // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay() |
| 3885 // The leak comes from either ElementVisibilityObserver or IntersectionObserve
r. Should keep an eye on it. | 3965 // is never called. The leak comes from either ElementVisibilityObserver or |
| 3886 // See https://crbug.com/627539 | 3966 // IntersectionObserver. Should keep an eye on it. See |
| 3967 // https://crbug.com/627539 |
| 3887 m_autoplayVisibilityObserver->stop(); | 3968 m_autoplayVisibilityObserver->stop(); |
| 3888 m_autoplayVisibilityObserver = nullptr; | 3969 m_autoplayVisibilityObserver = nullptr; |
| 3889 } | 3970 } |
| 3890 | 3971 |
| 3891 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) { | 3972 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) { |
| 3892 if (!ThreadHeap::isHeapObjectAlive(m_audioSourceNode)) { | 3973 if (!ThreadHeap::isHeapObjectAlive(m_audioSourceNode)) { |
| 3893 getAudioSourceProvider().setClient(nullptr); | 3974 getAudioSourceProvider().setClient(nullptr); |
| 3894 m_audioSourceNode = nullptr; | 3975 m_audioSourceNode = nullptr; |
| 3895 } | 3976 } |
| 3896 } | 3977 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3990 | 4071 |
| 3991 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() | 4072 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() |
| 3992 const { | 4073 const { |
| 3993 IntRect result; | 4074 IntRect result; |
| 3994 if (LayoutObject* object = m_element->layoutObject()) | 4075 if (LayoutObject* object = m_element->layoutObject()) |
| 3995 result = object->absoluteBoundingBoxRect(); | 4076 result = object->absoluteBoundingBoxRect(); |
| 3996 return result; | 4077 return result; |
| 3997 } | 4078 } |
| 3998 | 4079 |
| 3999 } // namespace blink | 4080 } // namespace blink |
| OLD | NEW |