| /* |
| * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| |
| #if ENABLE(VIDEO_TRACK) |
| |
| #include "TrackListBase.h" |
| |
| #include "EventNames.h" |
| #include "HTMLMediaElement.h" |
| #include "ScriptExecutionContext.h" |
| #include "TrackEvent.h" |
| #include <wtf/IsoMallocInlines.h> |
| |
| namespace WebCore { |
| |
| WTF_MAKE_ISO_ALLOCATED_IMPL(TrackListBase); |
| |
| TrackListBase::TrackListBase(HTMLMediaElement* element, ScriptExecutionContext* context) |
| : ActiveDOMObject(context) |
| , m_element(element) |
| , m_asyncEventQueue(MainThreadGenericEventQueue::create(*this)) |
| { |
| ASSERT(!context || is<Document>(context)); |
| suspendIfNeeded(); |
| } |
| |
| TrackListBase::~TrackListBase() |
| { |
| clearElement(); |
| } |
| |
| void TrackListBase::clearElement() |
| { |
| m_element = nullptr; |
| for (auto& track : m_inbandTracks) { |
| track->setMediaElement(nullptr); |
| track->clearClient(); |
| } |
| } |
| |
| Element* TrackListBase::element() const |
| { |
| return m_element; |
| } |
| |
| unsigned TrackListBase::length() const |
| { |
| return m_inbandTracks.size(); |
| } |
| |
| void TrackListBase::remove(TrackBase& track, bool scheduleEvent) |
| { |
| size_t index = m_inbandTracks.find(&track); |
| if (index == notFound) |
| return; |
| |
| if (track.mediaElement()) { |
| ASSERT(track.mediaElement() == m_element); |
| track.setMediaElement(nullptr); |
| } |
| |
| Ref<TrackBase> trackRef = *m_inbandTracks[index]; |
| |
| m_inbandTracks.remove(index); |
| |
| if (scheduleEvent) |
| scheduleRemoveTrackEvent(WTFMove(trackRef)); |
| } |
| |
| bool TrackListBase::contains(TrackBase& track) const |
| { |
| return m_inbandTracks.find(&track) != notFound; |
| } |
| |
| void TrackListBase::scheduleTrackEvent(const AtomString& eventName, Ref<TrackBase>&& track) |
| { |
| m_asyncEventQueue->enqueueEvent(TrackEvent::create(eventName, Event::CanBubble::No, Event::IsCancelable::No, WTFMove(track))); |
| } |
| |
| void TrackListBase::scheduleAddTrackEvent(Ref<TrackBase>&& track) |
| { |
| // 4.8.10.5 Loading the media resource |
| // ... |
| // Fire a trusted event with the name addtrack, that does not bubble and is |
| // not cancelable, and that uses the TrackEvent interface, with the track |
| // attribute initialized to the new AudioTrack object, at this |
| // AudioTrackList object. |
| // ... |
| // Fire a trusted event with the name addtrack, that does not bubble and is |
| // not cancelable, and that uses the TrackEvent interface, with the track |
| // attribute initialized to the new VideoTrack object, at this |
| // VideoTrackList object. |
| |
| // 4.8.10.12.3 Sourcing out-of-band text tracks |
| // 4.8.10.12.4 Text track API |
| // ... then queue a task to fire an event with the name addtrack, that does not |
| // bubble and is not cancelable, and that uses the TrackEvent interface, with |
| // the track attribute initialized to the text track's TextTrack object, at |
| // the media element's textTracks attribute's TextTrackList object. |
| scheduleTrackEvent(eventNames().addtrackEvent, WTFMove(track)); |
| } |
| |
| void TrackListBase::scheduleRemoveTrackEvent(Ref<TrackBase>&& track) |
| { |
| // 4.8.10.6 Offsets into the media resource |
| // If at any time the user agent learns that an audio or video track has |
| // ended and all media data relating to that track corresponds to parts of |
| // the media timeline that are before the earliest possible position, the |
| // user agent may queue a task to remove the track from the audioTracks |
| // attribute's AudioTrackList object or the videoTracks attribute's |
| // VideoTrackList object as appropriate and then fire a trusted event |
| // with the name removetrack, that does not bubble and is not cancelable, |
| // and that uses the TrackEvent interface, with the track attribute |
| // initialized to the AudioTrack or VideoTrack object representing the |
| // track, at the media element's aforementioned AudioTrackList or |
| // VideoTrackList object. |
| |
| // 4.8.10.12.3 Sourcing out-of-band text tracks |
| // When a track element's parent element changes and the old parent was a |
| // media element, then the user agent must remove the track element's |
| // corresponding text track from the media element's list of text tracks, |
| // and then queue a task to fire a trusted event with the name removetrack, |
| // that does not bubble and is not cancelable, and that uses the TrackEvent |
| // interface, with the track attribute initialized to the text track's |
| // TextTrack object, at the media element's textTracks attribute's |
| // TextTrackList object. |
| scheduleTrackEvent(eventNames().removetrackEvent, WTFMove(track)); |
| } |
| |
| void TrackListBase::scheduleChangeEvent() |
| { |
| // 4.8.10.6 Offsets into the media resource |
| // Whenever an audio track in an AudioTrackList is enabled or disabled, the |
| // user agent must queue a task to fire a simple event named change at the |
| // AudioTrackList object. |
| // ... |
| // Whenever a track in a VideoTrackList that was previously not selected is |
| // selected, the user agent must queue a task to fire a simple event named |
| // change at the VideoTrackList object. |
| m_asyncEventQueue->enqueueEvent(Event::create(eventNames().changeEvent, Event::CanBubble::No, Event::IsCancelable::No)); |
| } |
| |
| bool TrackListBase::isChangeEventScheduled() const |
| { |
| return m_asyncEventQueue->hasPendingEventsOfType(eventNames().changeEvent); |
| } |
| |
| bool TrackListBase::isAnyTrackEnabled() const |
| { |
| for (auto& track : m_inbandTracks) { |
| if (track->enabled()) |
| return true; |
| } |
| return false; |
| } |
| |
| } // namespace WebCore |
| |
| #endif |