diff options
Diffstat (limited to 'Source/WebCore/html/track/InbandGenericTextTrack.cpp')
-rw-r--r-- | Source/WebCore/html/track/InbandGenericTextTrack.cpp | 239 |
1 files changed, 134 insertions, 105 deletions
diff --git a/Source/WebCore/html/track/InbandGenericTextTrack.cpp b/Source/WebCore/html/track/InbandGenericTextTrack.cpp index d807dc2d3..8065c8843 100644 --- a/Source/WebCore/html/track/InbandGenericTextTrack.cpp +++ b/Source/WebCore/html/track/InbandGenericTextTrack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * 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 COMPUTER, INC. ``AS IS'' AND ANY + * 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 COMPUTER, INC. OR + * 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 @@ -24,170 +24,199 @@ */ #include "config.h" +#include "InbandGenericTextTrack.h" #if ENABLE(VIDEO_TRACK) -#include "InbandGenericTextTrack.h" - -#include "ExceptionCodePlaceholder.h" +#include "DataCue.h" #include "HTMLMediaElement.h" #include "InbandTextTrackPrivate.h" #include "Logging.h" +#include "VTTRegionList.h" #include <math.h> #include <wtf/text/CString.h> namespace WebCore { -GenericTextTrackCueMap::GenericTextTrackCueMap() +void GenericTextTrackCueMap::add(GenericCueData& cueData, TextTrackCueGeneric& cue) { + m_dataToCueMap.add(&cueData, &cue); + m_cueToDataMap.add(&cue, &cueData); } -GenericTextTrackCueMap::~GenericTextTrackCueMap() +TextTrackCueGeneric* GenericTextTrackCueMap::find(GenericCueData& cueData) { + return m_dataToCueMap.get(&cueData); } -void GenericTextTrackCueMap::add(GenericCueData* cueData, TextTrackCueGeneric* cue) +GenericCueData* GenericTextTrackCueMap::find(TextTrackCue& cue) { - m_dataToCueMap.add(cueData, cue); - m_cueToDataMap.add(cue, cueData); -} - -PassRefPtr<TextTrackCueGeneric> GenericTextTrackCueMap::find(GenericCueData* cueData) -{ - CueDataToCueMap::iterator iter = m_dataToCueMap.find(cueData); - if (iter == m_dataToCueMap.end()) - return 0; - - return iter->value; + return m_cueToDataMap.get(&cue); } -PassRefPtr<GenericCueData> GenericTextTrackCueMap::find(TextTrackCue* cue) +void GenericTextTrackCueMap::remove(GenericCueData& cueData) { - CueToDataMap::iterator iter = m_cueToDataMap.find(cue); - if (iter == m_cueToDataMap.end()) - return 0; - - return iter->value; -} - -void GenericTextTrackCueMap::remove(GenericCueData* cueData) -{ - RefPtr<TextTrackCueGeneric> cue = find(cueData); - - if (cue) + if (auto cue = m_dataToCueMap.take(&cueData)) m_cueToDataMap.remove(cue); - m_dataToCueMap.remove(cueData); } -void GenericTextTrackCueMap::remove(TextTrackCue* cue) +void GenericTextTrackCueMap::remove(TextTrackCue& cue) { - RefPtr<GenericCueData> genericData = find(cue); - if (genericData) { - m_dataToCueMap.remove(genericData); - m_cueToDataMap.remove(cue); - } + if (auto data = m_cueToDataMap.take(&cue)) + m_dataToCueMap.remove(data); } -PassRefPtr<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate) +inline InbandGenericTextTrack::InbandGenericTextTrack(ScriptExecutionContext& context, TextTrackClient& client, InbandTextTrackPrivate& trackPrivate) + : InbandTextTrack(context, client, trackPrivate) { - return adoptRef(new InbandGenericTextTrack(context, client, playerPrivate)); } -InbandGenericTextTrack::InbandGenericTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate) - : InbandTextTrack(context, client, trackPrivate) +Ref<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext& context, TextTrackClient& client, InbandTextTrackPrivate& trackPrivate) { + return adoptRef(*new InbandGenericTextTrack(context, client, trackPrivate)); } InbandGenericTextTrack::~InbandGenericTextTrack() { } -void InbandGenericTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, GenericCueData* cueData) +void InbandGenericTextTrack::updateCueFromCueData(TextTrackCueGeneric& cue, GenericCueData& cueData) { - cue->willChange(); - - cue->setStartTime(cueData->startTime(), IGNORE_EXCEPTION); - double endTime = cueData->endTime(); - if (std::isinf(endTime) && mediaElement()) - endTime = mediaElement()->duration(); - cue->setEndTime(endTime, IGNORE_EXCEPTION); - cue->setText(cueData->content()); - cue->setId(cueData->id()); - cue->setBaseFontSizeRelativeToVideoHeight(cueData->baseFontSize()); - cue->setFontSizeMultiplier(cueData->relativeFontSize()); - cue->setFontName(cueData->fontName()); - - if (cueData->position() > 0) - cue->setPosition(lround(cueData->position()), IGNORE_EXCEPTION); - if (cueData->line() > 0) - cue->setLine(lround(cueData->line()), IGNORE_EXCEPTION); - if (cueData->size() > 0) - cue->setSize(lround(cueData->size()), IGNORE_EXCEPTION); - if (cueData->backgroundColor().isValid()) - cue->setBackgroundColor(cueData->backgroundColor().rgb()); - if (cueData->foregroundColor().isValid()) - cue->setForegroundColor(cueData->foregroundColor().rgb()); - if (cueData->highlightColor().isValid()) - cue->setHighlightColor(cueData->highlightColor().rgb()); - - if (cueData->align() == GenericCueData::Start) - cue->setAlign(ASCIILiteral("start"), IGNORE_EXCEPTION); - else if (cueData->align() == GenericCueData::Middle) - cue->setAlign(ASCIILiteral("middle"), IGNORE_EXCEPTION); - else if (cueData->align() == GenericCueData::End) - cue->setAlign(ASCIILiteral("end"), IGNORE_EXCEPTION); - cue->setSnapToLines(false); - - cue->didChange(); + cue.willChange(); + + cue.setStartTime(cueData.startTime()); + MediaTime endTime = cueData.endTime(); + if (endTime.isPositiveInfinite() && mediaElement()) + endTime = mediaElement()->durationMediaTime(); + cue.setEndTime(endTime); + cue.setText(cueData.content()); + cue.setId(cueData.id()); + cue.setBaseFontSizeRelativeToVideoHeight(cueData.baseFontSize()); + cue.setFontSizeMultiplier(cueData.relativeFontSize()); + cue.setFontName(cueData.fontName()); + + if (cueData.position() > 0) + cue.setPosition(std::round(cueData.position())); + if (cueData.line() > 0) + cue.setLine(std::round(cueData.line())); + if (cueData.size() > 0) + cue.setSize(std::round(cueData.size())); + if (cueData.backgroundColor().isValid()) + cue.setBackgroundColor(cueData.backgroundColor().rgb()); + if (cueData.foregroundColor().isValid()) + cue.setForegroundColor(cueData.foregroundColor().rgb()); + if (cueData.highlightColor().isValid()) + cue.setHighlightColor(cueData.highlightColor().rgb()); + + if (cueData.align() == GenericCueData::Start) + cue.setAlign(ASCIILiteral("start")); + else if (cueData.align() == GenericCueData::Middle) + cue.setAlign(ASCIILiteral("middle")); + else if (cueData.align() == GenericCueData::End) + cue.setAlign(ASCIILiteral("end")); + cue.setSnapToLines(false); + + cue.didChange(); } -void InbandGenericTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, PassRefPtr<GenericCueData> prpCueData) +void InbandGenericTextTrack::addGenericCue(GenericCueData& cueData) { - ASSERT_UNUSED(trackPrivate, trackPrivate == m_private); - - RefPtr<GenericCueData> cueData = prpCueData; - if (m_cueMap.find(cueData.get())) + if (m_cueMap.find(cueData)) return; - RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(*scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content()); - updateCueFromCueData(cue.get(), cueData.get()); - if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) { - LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data()); + auto cue = TextTrackCueGeneric::create(*scriptExecutionContext(), cueData.startTime(), cueData.endTime(), cueData.content()); + updateCueFromCueData(cue.get(), cueData); + if (hasCue(cue.ptr(), TextTrackCue::IgnoreDuration)) { + LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%s, end=%s, content=\"%s\"\n", toString(cueData.startTime()).utf8().data(), toString(cueData.endTime()).utf8().data(), cueData.content().utf8().data()); return; } - if (cueData->status() != GenericCueData::Complete) - m_cueMap.add(cueData.get(), cue.get()); + LOG(Media, "InbandGenericTextTrack::addGenericCue added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData.startTime().toDouble(), cueData.endTime().toDouble(), cueData.content().utf8().data()); - addCue(cue); + if (cueData.status() != GenericCueData::Complete) + m_cueMap.add(cueData, cue); + + addCue(WTFMove(cue)); } -void InbandGenericTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData) +void InbandGenericTextTrack::updateGenericCue(GenericCueData& cueData) { - RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData); + auto* cue = m_cueMap.find(cueData); if (!cue) return; - updateCueFromCueData(cue.get(), cueData); + updateCueFromCueData(*cue, cueData); - if (cueData->status() == GenericCueData::Complete) + if (cueData.status() == GenericCueData::Complete) m_cueMap.remove(cueData); } -void InbandGenericTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData) +void InbandGenericTextTrack::removeGenericCue(GenericCueData& cueData) { - RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData); + auto* cue = m_cueMap.find(cueData); if (cue) { - LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data()); - removeCue(cue.get(), IGNORE_EXCEPTION); - } else - m_cueMap.remove(cueData); + LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%s, end=%s, content=\"%s\"\n", toString(cueData.startTime()).utf8().data(), toString(cueData.endTime()).utf8().data(), cueData.content().utf8().data()); + removeCue(*cue); + } else { + LOG(Media, "InbandGenericTextTrack::removeGenericCue UNABLE to find cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData.startTime().toDouble(), cueData.endTime().toDouble(), cueData.content().utf8().data()); + } +} + +ExceptionOr<void> InbandGenericTextTrack::removeCue(TextTrackCue& cue) +{ + auto result = TextTrack::removeCue(cue); + if (!result.hasException()) + m_cueMap.remove(cue); + return result; +} + +WebVTTParser& InbandGenericTextTrack::parser() +{ + if (!m_webVTTParser) + m_webVTTParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), scriptExecutionContext()); + return *m_webVTTParser; +} + +void InbandGenericTextTrack::parseWebVTTCueData(const ISOWebVTTCue& cueData) +{ + parser().parseCueData(cueData); +} + +void InbandGenericTextTrack::parseWebVTTFileHeader(String&& header) +{ + parser().parseFileHeader(WTFMove(header)); +} + +void InbandGenericTextTrack::newCuesParsed() +{ + Vector<RefPtr<WebVTTCueData>> cues; + parser().getNewCues(cues); + + for (auto& cueData : cues) { + auto vttCue = VTTCue::create(*scriptExecutionContext(), *cueData); + + if (hasCue(vttCue.ptr(), TextTrackCue::IgnoreDuration)) { + LOG(Media, "InbandGenericTextTrack::newCuesParsed ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", vttCue->startTime(), vttCue->endTime(), vttCue->text().utf8().data()); + return; + } + addCue(WTFMove(vttCue)); + } +} + +void InbandGenericTextTrack::newRegionsParsed() +{ + Vector<RefPtr<VTTRegion>> newRegions; + parser().getNewRegions(newRegions); + + for (auto& region : newRegions) { + region->setTrack(this); + regions()->add(region.releaseNonNull()); + } } -void InbandGenericTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec) +void InbandGenericTextTrack::fileFailedToParse() { - m_cueMap.remove(cue); - TextTrack::removeCue(cue, ec); + LOG(Media, "Error parsing WebVTT stream."); } } // namespace WebCore |