Title: [148540] trunk/Source/WebCore
Revision
148540
Author
eric.carl...@apple.com
Date
2013-04-16 13:42:49 -0700 (Tue, 16 Apr 2013)

Log Message

[Mac] in-band cues sometimes displayed late
https://bugs.webkit.org/show_bug.cgi?id=114629

Reviewed by Jer Noble.

No new tests, this deals with a platform-specific issue that is extremely timing dependent.

* html/track/InbandTextTrack.cpp:
(WebCore::TextTrackCueMap::add): New, two way cue data <-> cue map.
(WebCore::TextTrackCueMap::find): 
(WebCore::TextTrackCueMap::remove):
(WebCore::InbandTextTrack::updateCueFromCueData): New, update an existing cue. Set cue end time
    to video duration if it is unknown.
(WebCore::InbandTextTrack::addGenericCue): Look for existing cues without considering duration
    so we can match incomplete cues.
(WebCore::InbandTextTrack::updateGenericCue): New, update an existing cue. This allows us to 
    add in-band cues as soon as we get them from the media engine and update them as more
    information becomes available.
(WebCore::InbandTextTrack::removeGenericCue): New, remove an existing cue. This is necessary
    because we never want to keep an incomplete cue when a seek happens.
(WebCore::InbandTextTrack::removeCue): New, base class override so we can keep the two way
    map up to date.
* html/track/InbandTextTrack.h:

* html/track/TextTrack.cpp:
(WebCore::TextTrack::addCue): TextTrack::removeCue takes a RefPtr.
(WebCore::TextTrack::removeCue): Take a RefPtr.
(WebCore::TextTrack::hasCue): Allow caller to request match without considering end time.
* html/track/TextTrack.h:

* html/track/TextTrackCue.cpp:
(WebCore::TextTrackCue::TextTrackCue): Initialize m_processingCueChanges.
(WebCore::TextTrackCue::willChange): Renamed from cueWillChange. Use m_processingCueChanges
    to avoid thrashing the track when many cue properties will change.
(WebCore::TextTrackCue::didChange): Renamed from cueDidChange. Use m_processingCueChanges
    to avoid thrashing the track when many cue properties will change.
(WebCore::TextTrackCue::setId): cueWillChange -> willChange. cueDidChange -> didChange. 
(WebCore::TextTrackCue::setStartTime): Ditto.
(WebCore::TextTrackCue::setEndTime): Ditto.
(WebCore::TextTrackCue::setPauseOnExit): Ditto.
(WebCore::TextTrackCue::setVertical): Ditto.
(WebCore::TextTrackCue::setSnapToLines): Ditto.
(WebCore::TextTrackCue::setLine): Ditto.
(WebCore::TextTrackCue::setPosition): Ditto.
(WebCore::TextTrackCue::setSize): Ditto.
(WebCore::TextTrackCue::setAlign): Ditto.
(WebCore::TextTrackCue::setText): Ditto.
(WebCore::TextTrackCue::setRegionId): Ditto.
(WebCore::TextTrackCue::isEqual): Renamed from operator==, take match rules param.
* html/track/TextTrackCue.h:

* html/track/TextTrackCueGeneric.cpp:
(WebCore::TextTrackCueGeneric::isEqual): Renamed from operator==, take match rules param.
* html/track/TextTrackCueGeneric.h:

* platform/graphics/InbandTextTrackPrivateClient.h: Make GenericCueData refcounted.
(WebCore::GenericCueData::create): New.
(WebCore::GenericCueData::status): Ditto.
(WebCore::GenericCueData::setStatus): Ditto.
(WebCore::GenericCueData::GenericCueData):

* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
(WebCore::InbandTextTrackPrivateAVF::processCue): Add cues as soon as we get them from the media
    engine, update duration once we know it.
(WebCore::InbandTextTrackPrivateAVF::resetCueValues): Tell the client to remove all incomplete
    cues we have delivered.
* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h:

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Do not flush cues when seek completes,
    we did that when the seek started and cues can be delivered before we get the the 
    seek completed  notification.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (148539 => 148540)


--- trunk/Source/WebCore/ChangeLog	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/ChangeLog	2013-04-16 20:42:49 UTC (rev 148540)
@@ -1,3 +1,78 @@
+2013-04-16  Eric Carlson  <eric.carl...@apple.com>
+
+        [Mac] in-band cues sometimes displayed late
+        https://bugs.webkit.org/show_bug.cgi?id=114629
+
+        Reviewed by Jer Noble.
+
+        No new tests, this deals with a platform-specific issue that is extremely timing dependent.
+
+        * html/track/InbandTextTrack.cpp:
+        (WebCore::TextTrackCueMap::add): New, two way cue data <-> cue map.
+        (WebCore::TextTrackCueMap::find): 
+        (WebCore::TextTrackCueMap::remove):
+        (WebCore::InbandTextTrack::updateCueFromCueData): New, update an existing cue. Set cue end time
+            to video duration if it is unknown.
+        (WebCore::InbandTextTrack::addGenericCue): Look for existing cues without considering duration
+            so we can match incomplete cues.
+        (WebCore::InbandTextTrack::updateGenericCue): New, update an existing cue. This allows us to 
+            add in-band cues as soon as we get them from the media engine and update them as more
+            information becomes available.
+        (WebCore::InbandTextTrack::removeGenericCue): New, remove an existing cue. This is necessary
+            because we never want to keep an incomplete cue when a seek happens.
+        (WebCore::InbandTextTrack::removeCue): New, base class override so we can keep the two way
+            map up to date.
+        * html/track/InbandTextTrack.h:
+
+        * html/track/TextTrack.cpp:
+        (WebCore::TextTrack::addCue): TextTrack::removeCue takes a RefPtr.
+        (WebCore::TextTrack::removeCue): Take a RefPtr.
+        (WebCore::TextTrack::hasCue): Allow caller to request match without considering end time.
+        * html/track/TextTrack.h:
+
+        * html/track/TextTrackCue.cpp:
+        (WebCore::TextTrackCue::TextTrackCue): Initialize m_processingCueChanges.
+        (WebCore::TextTrackCue::willChange): Renamed from cueWillChange. Use m_processingCueChanges
+            to avoid thrashing the track when many cue properties will change.
+        (WebCore::TextTrackCue::didChange): Renamed from cueDidChange. Use m_processingCueChanges
+            to avoid thrashing the track when many cue properties will change.
+        (WebCore::TextTrackCue::setId): cueWillChange -> willChange. cueDidChange -> didChange. 
+        (WebCore::TextTrackCue::setStartTime): Ditto.
+        (WebCore::TextTrackCue::setEndTime): Ditto.
+        (WebCore::TextTrackCue::setPauseOnExit): Ditto.
+        (WebCore::TextTrackCue::setVertical): Ditto.
+        (WebCore::TextTrackCue::setSnapToLines): Ditto.
+        (WebCore::TextTrackCue::setLine): Ditto.
+        (WebCore::TextTrackCue::setPosition): Ditto.
+        (WebCore::TextTrackCue::setSize): Ditto.
+        (WebCore::TextTrackCue::setAlign): Ditto.
+        (WebCore::TextTrackCue::setText): Ditto.
+        (WebCore::TextTrackCue::setRegionId): Ditto.
+        (WebCore::TextTrackCue::isEqual): Renamed from operator==, take match rules param.
+        * html/track/TextTrackCue.h:
+
+        * html/track/TextTrackCueGeneric.cpp:
+        (WebCore::TextTrackCueGeneric::isEqual): Renamed from operator==, take match rules param.
+        * html/track/TextTrackCueGeneric.h:
+
+        * platform/graphics/InbandTextTrackPrivateClient.h: Make GenericCueData refcounted.
+        (WebCore::GenericCueData::create): New.
+        (WebCore::GenericCueData::status): Ditto.
+        (WebCore::GenericCueData::setStatus): Ditto.
+        (WebCore::GenericCueData::GenericCueData):
+
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
+        (WebCore::InbandTextTrackPrivateAVF::processCue): Add cues as soon as we get them from the media
+            engine, update duration once we know it.
+        (WebCore::InbandTextTrackPrivateAVF::resetCueValues): Tell the client to remove all incomplete
+            cues we have delivered.
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h:
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Do not flush cues when seek completes,
+            we did that when the seek started and cues can be delivered before we get the the 
+            seek completed  notification.
+
 2013-04-16  James Craig  <ja...@cookiecrook.com>
 
         dfn element should be exposed as AXGroup:AXDefinition

Modified: trunk/Source/WebCore/html/track/InbandTextTrack.cpp (148539 => 148540)


--- trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -32,9 +32,9 @@
 #include "Document.h"
 #include "Event.h"
 #include "ExceptionCodePlaceholder.h"
+#include "HTMLMediaElement.h"
 #include "InbandTextTrackPrivate.h"
 #include "Logging.h"
-#include "MediaPlayer.h"
 #include "TextTrackCueGeneric.h"
 #include "TextTrackCueList.h"
 #include <math.h>
@@ -42,6 +42,49 @@
 
 namespace WebCore {
 
+void TextTrackCueMap::add(GenericCueData* cueData, TextTrackCueGeneric* cue)
+{
+    m_dataToCueMap.add(cueData, cue);
+    m_cueToDataMap.add(cue, cueData);
+}
+
+PassRefPtr<TextTrackCueGeneric> TextTrackCueMap::find(GenericCueData* cueData)
+{
+    GenericCueDataToCueMap::iterator iter = m_dataToCueMap.find(cueData);
+    if (iter == m_dataToCueMap.end())
+        return 0;
+    
+    return iter->value;
+}
+
+PassRefPtr<GenericCueData> TextTrackCueMap::find(TextTrackCueGeneric* cue)
+{
+    GenericCueToCueDataMap::iterator iter = m_cueToDataMap.find(cue);
+    if (iter == m_cueToDataMap.end())
+        return 0;
+    
+    return iter->value;
+}
+
+void TextTrackCueMap::remove(GenericCueData* cueData)
+{
+    RefPtr<TextTrackCueGeneric> cue = find(cueData);
+
+    if (cue)
+        m_cueToDataMap.remove(cue);
+    m_dataToCueMap.remove(cueData);
+}
+
+void TextTrackCueMap::remove(TextTrackCueGeneric* cue)
+{
+    RefPtr<GenericCueData> cueData = find(cue);
+
+    if (cueData)
+        m_dataToCueMap.remove(cueData);
+    m_cueToDataMap.remove(cue);
+}
+
+
 PassRefPtr<InbandTextTrack> InbandTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
 {
     return adoptRef(new InbandTextTrack(context, client, playerPrivate));
@@ -136,13 +179,16 @@
     return m_private->textTrackIndex();
 }
 
-void InbandTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, GenericCueData* cueData)
+void InbandTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, GenericCueData* cueData)
 {
-    UNUSED_PARAM(trackPrivate);
-    ASSERT(trackPrivate == m_private);
+    cue->willChange();
 
-    RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
-
+    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());
@@ -167,30 +213,57 @@
         cue->setAlign(ASCIILiteral("end"), IGNORE_EXCEPTION);
     cue->setSnapToLines(false);
 
-    if (hasCue(cue.get())) {
-        LOG(Media, "InbandTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n",
-            cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
+    cue->didChange();
+}
+    
+void InbandTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, PassRefPtr<GenericCueData> prpCueData)
+{
+    UNUSED_PARAM(trackPrivate);
+    ASSERT(trackPrivate == m_private);
+
+    RefPtr<GenericCueData> cueData = prpCueData;
+    if (m_cueMap.find(cueData.get()))
         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, "InbandTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
+        return;
     }
 
+    m_cueMap.add(cueData.get(), cue.get());
+
     addCue(cue);
 }
 
-void InbandTextTrack::addWebVTTCue(InbandTextTrackPrivate* trackPrivate, double start, double end, const String& id, const String& content, const String& settings)
+void InbandTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
 {
-    UNUSED_PARAM(trackPrivate);
-    ASSERT(trackPrivate == m_private);
+    RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
+    if (!cue)
+        return;
 
-    RefPtr<TextTrackCue> cue = TextTrackCue::create(scriptExecutionContext(), start, end, content);
-    cue->setId(id);
-    cue->setCueSettings(settings);
+    updateCueFromCueData(cue.get(), cueData);
     
-    if (hasCue(cue.get()))
-        return;
+    if (cueData->status() == GenericCueData::Complete)
+        m_cueMap.remove(cueData);
+}
 
-    addCue(cue);
+void InbandTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
+{
+    RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
+    if (cue)
+        removeCue(cue.get(), IGNORE_EXCEPTION);
+    else
+        m_cueMap.remove(cueData);
 }
 
+void InbandTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
+{
+    m_cueMap.remove(static_cast<TextTrackCueGeneric*>(cue));
+    TextTrack::removeCue(cue, ec);
+}
+    
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/track/InbandTextTrack.h (148539 => 148540)


--- trunk/Source/WebCore/html/track/InbandTextTrack.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -31,15 +31,36 @@
 #include "InbandTextTrackPrivate.h"
 #include "InbandTextTrackPrivateClient.h"
 #include "TextTrack.h"
+#include "TextTrackCueGeneric.h"
 #include <wtf/RefPtr.h>
 
 namespace WebCore {
 
 class Document;
 class InbandTextTrackPrivate;
-class MediaPlayer;
 class TextTrackCue;
 
+class TextTrackCueMap {
+public:
+    TextTrackCueMap() { }
+    virtual ~TextTrackCueMap() { }
+
+    void add(GenericCueData*, TextTrackCueGeneric*);
+
+    void remove(GenericCueData*);
+    void remove(TextTrackCueGeneric*);
+    
+    PassRefPtr<GenericCueData> find(TextTrackCueGeneric*);
+    PassRefPtr<TextTrackCueGeneric> find(GenericCueData*);
+    
+private:
+    typedef HashMap<RefPtr<TextTrackCueGeneric>, RefPtr<GenericCueData> > GenericCueToCueDataMap;
+    typedef HashMap<RefPtr<GenericCueData>, RefPtr<TextTrackCueGeneric> > GenericCueDataToCueMap;
+    
+    GenericCueToCueDataMap m_cueToDataMap;
+    GenericCueDataToCueMap m_dataToCueMap;
+};
+
 class InbandTextTrack : public TextTrack, public InbandTextTrackPrivateClient {
 public:
     static PassRefPtr<InbandTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
@@ -55,13 +76,19 @@
 private:
     InbandTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
 
-    virtual void addGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
-    virtual void addWebVTTCue(InbandTextTrackPrivate*, double, double, const String&, const String&, const String&) OVERRIDE;
+    virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) OVERRIDE;
+    virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
+    virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
+    virtual void removeCue(TextTrackCue*, ExceptionCode&) OVERRIDE;
 
+    PassRefPtr<TextTrackCueGeneric> createCue(PassRefPtr<GenericCueData>);
+    void updateCueFromCueData(TextTrackCueGeneric*, GenericCueData*);
+
 #if USE(PLATFORM_TEXT_TRACK_MENU)
     virtual InbandTextTrackPrivate* privateTrack() OVERRIDE { return m_private.get(); }
 #endif
 
+    TextTrackCueMap m_cueMap;
     RefPtr<InbandTextTrackPrivate> m_private;
 };
 

Modified: trunk/Source/WebCore/html/track/TextTrack.cpp (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrack.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrack.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -466,7 +466,7 @@
     return m_renderedTrackIndex;
 }
 
-bool TextTrack::hasCue(TextTrackCue* cue)
+bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
 {
     if (cue->startTime() < 0 || cue->endTime() < 0)
         return false;
@@ -505,7 +505,7 @@
                 if (!existingCue || cue->startTime() > existingCue->startTime())
                     return false;
 
-                if (*existingCue != *cue)
+                if (!existingCue->isEqual(*cue, match))
                     continue;
                 
                 return true;
@@ -514,7 +514,7 @@
         
         size_t index = (searchStart + searchEnd) / 2;
         existingCue = m_cues->item(index);
-        if (cue->startTime() < existingCue->startTime() || (cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
+        if (cue->startTime() < existingCue->startTime() || (match != TextTrackCue::IgnoreDuration && cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
             searchEnd = index;
         else
             searchStart = index + 1;

Modified: trunk/Source/WebCore/html/track/TextTrack.h (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrack.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrack.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -30,6 +30,7 @@
 #if ENABLE(VIDEO_TRACK)
 
 #include "ExceptionCode.h"
+#include "TextTrackCue.h"
 #include "TrackBase.h"
 #include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
@@ -43,7 +44,6 @@
 
 class ScriptExecutionContext;
 class TextTrack;
-class TextTrackCue;
 class TextTrackCueList;
 #if ENABLE(WEBVTT_REGIONS)
 class TextTrackRegion;
@@ -108,9 +108,10 @@
     TextTrackClient* client() { return m_client; }
 
     void addCue(PassRefPtr<TextTrackCue>);
-    void removeCue(TextTrackCue*, ExceptionCode&);
-    bool hasCue(TextTrackCue*);
+    virtual void removeCue(TextTrackCue*, ExceptionCode&);
 
+    bool hasCue(TextTrackCue*, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
+
 #if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
     TextTrackRegionList* regions();
     void addRegion(PassRefPtr<TextTrackRegion>);

Modified: trunk/Source/WebCore/html/track/TextTrackCue.cpp (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrackCue.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrackCue.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -40,7 +40,6 @@
 #include "DocumentFragment.h"
 #include "Event.h"
 #include "HTMLDivElement.h"
-#include "HTMLMediaElement.h"
 #include "HTMLSpanElement.h"
 #include "Logging.h"
 #include "NodeTraversal.h"
@@ -194,6 +193,7 @@
     , m_textPosition(50)
     , m_cueSize(100)
     , m_cueIndex(invalidCueIndex)
+    , m_processingCueChanges(0)
     , m_writingDirection(Horizontal)
     , m_cueAlignment(Middle)
     , m_webVTTNodeTree(0)
@@ -235,14 +235,21 @@
     return m_displayTree;
 }
 
-void TextTrackCue::cueWillChange()
+void TextTrackCue::willChange()
 {
+    if (++m_processingCueChanges > 1)
+        return;
+
     if (m_track)
         m_track->cueWillChange(this);
 }
 
-void TextTrackCue::cueDidChange()
+void TextTrackCue::didChange()
 {
+    ASSERT(m_processingCueChanges);
+    if (--m_processingCueChanges)
+        return;
+
     if (m_track)
         m_track->cueDidChange(this);
 
@@ -264,9 +271,9 @@
     if (m_id == id)
         return;
 
-    cueWillChange();
+    willChange();
     m_id = id;
-    cueDidChange();
+    didChange();
 }
 
 void TextTrackCue::setStartTime(double value, ExceptionCode& ec)
@@ -280,10 +287,10 @@
     // TODO(93143): Add spec-compliant behavior for negative time values.
     if (m_startTime == value || value < 0)
         return;
-    
-    cueWillChange();
+
+    willChange();
     m_startTime = value;
-    cueDidChange();
+    didChange();
 }
     
 void TextTrackCue::setEndTime(double value, ExceptionCode& ec)
@@ -297,10 +304,10 @@
     // TODO(93143): Add spec-compliant behavior for negative time values.
     if (m_endTime == value || value < 0)
         return;
-    
-    cueWillChange();
+
+    willChange();
     m_endTime = value;
-    cueDidChange();
+    didChange();
 }
     
 void TextTrackCue::setPauseOnExit(bool value)
@@ -308,9 +315,7 @@
     if (m_pauseOnExit == value)
         return;
     
-    cueWillChange();
     m_pauseOnExit = value;
-    cueDidChange();
 }
 
 const String& TextTrackCue::vertical() const
@@ -349,9 +354,9 @@
     if (direction == m_writingDirection)
         return;
 
-    cueWillChange();
+    willChange();
     m_writingDirection = direction;
-    cueDidChange();
+    didChange();
 }
 
 void TextTrackCue::setSnapToLines(bool value)
@@ -359,9 +364,9 @@
     if (m_snapToLines == value)
         return;
     
-    cueWillChange();
+    willChange();
     m_snapToLines = value;
-    cueDidChange();
+    didChange();
 }
 
 void TextTrackCue::setLine(int position, ExceptionCode& ec)
@@ -378,10 +383,10 @@
     if (m_linePosition == position)
         return;
 
-    cueWillChange();
+    willChange();
     m_linePosition = position;
     m_computedLinePosition = calculateComputedLinePosition();
-    cueDidChange();
+    didChange();
 }
 
 void TextTrackCue::setPosition(int position, ExceptionCode& ec)
@@ -398,9 +403,9 @@
     if (m_textPosition == position)
         return;
     
-    cueWillChange();
+    willChange();
     m_textPosition = position;
-    cueDidChange();
+    didChange();
 }
 
 void TextTrackCue::setSize(int size, ExceptionCode& ec)
@@ -417,9 +422,9 @@
     if (m_cueSize == size)
         return;
     
-    cueWillChange();
+    willChange();
     m_cueSize = size;
-    cueDidChange();
+    didChange();
 }
 
 const String& TextTrackCue::align() const
@@ -458,9 +463,9 @@
     if (alignment == m_cueAlignment)
         return;
 
-    cueWillChange();
+    willChange();
     m_cueAlignment = alignment;
-    cueDidChange();
+    didChange();
 }
     
 void TextTrackCue::setText(const String& text)
@@ -468,12 +473,12 @@
     if (m_content == text)
         return;
     
-    cueWillChange();
+    willChange();
     // Clear the document fragment but don't bother to create it again just yet as we can do that
     // when it is requested.
     m_webVTTNodeTree = 0;
     m_content = text;
-    cueDidChange();
+    didChange();
 }
 
 int TextTrackCue::cueIndex()
@@ -541,9 +546,9 @@
     if (m_regionId == regionId)
         return;
 
-    cueWillChange();
+    willChange();
     m_regionId = regionId;
-    cueDidChange();
+    didChange();
 }
 #endif
 
@@ -1153,12 +1158,12 @@
     return &m_eventTargetData;
 }
 
-bool TextTrackCue::operator==(const TextTrackCue& cue) const
+bool TextTrackCue::isEqual(const TextTrackCue& cue, CueMatchRules match) const
 {
     if (cueType() != cue.cueType())
         return false;
-
-    if (m_endTime != cue.endTime())
+    
+    if (match != IgnoreDuration && m_endTime != cue.endTime())
         return false;
     if (m_startTime != cue.startTime())
         return false;
@@ -1179,7 +1184,6 @@
     
     return true;
 }
-
 void TextTrackCue::setFontSize(int fontSize, const IntSize&, bool important)
 {
     if (!hasDisplayTree() || !fontSize)

Modified: trunk/Source/WebCore/html/track/TextTrackCue.h (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrackCue.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrackCue.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -37,7 +37,6 @@
 #include "EventTarget.h"
 #include "HTMLDivElement.h"
 #include "HTMLElement.h"
-#include "TextTrack.h"
 #include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
 
@@ -179,18 +178,21 @@
 
     virtual void setFontSize(int, const IntSize&, bool important);
 
-    virtual bool operator==(const TextTrackCue&) const;
-    virtual bool operator!=(const TextTrackCue& cue) const
-    {
-        return !(*this == cue);
-    }
-    
+    enum CueMatchRules {
+        MatchAllFields,
+        IgnoreDuration,
+    };
+    virtual bool isEqual(const TextTrackCue&, CueMatchRules) const;
+
     enum CueType {
         Generic,
         WebVTT
     };
     virtual CueType cueType() const { return WebVTT; }
 
+    void willChange();
+    void didChange();
+    
     DEFINE_ATTRIBUTE_EVENT_LISTENER(enter);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(exit);
 
@@ -218,9 +220,6 @@
     void determineTextDirection();
     void calculateDisplayParameters();
 
-    void cueWillChange();
-    void cueDidChange();
-
     virtual void refEventTarget() { ref(); }
     virtual void derefEventTarget() { deref(); }
 
@@ -247,6 +246,7 @@
     int m_textPosition;
     int m_cueSize;
     int m_cueIndex;
+    int m_processingCueChanges;
 
     WritingDirection m_writingDirection;
 

Modified: trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -151,7 +151,7 @@
     LOG(Media, "TextTrackCueGeneric::setFontSize - setting cue font size to %li", lround(size));
 }
     
-bool TextTrackCueGeneric::operator==(const TextTrackCue& cue) const
+bool TextTrackCueGeneric::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
 {
     if (cue.cueType() != TextTrackCue::Generic)
         return false;
@@ -169,7 +169,7 @@
     if (m_backgroundColor != other->backgroundColor())
         return false;
 
-    return TextTrackCue::operator==(cue);
+    return TextTrackCue::isEqual(cue, match);
 }
     
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/track/TextTrackCueGeneric.h (148539 => 148540)


--- trunk/Source/WebCore/html/track/TextTrackCueGeneric.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/html/track/TextTrackCueGeneric.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -70,11 +70,7 @@
 
     virtual void setFontSize(int, const IntSize&, bool important) OVERRIDE;
 
-    virtual bool operator==(const TextTrackCue&) const OVERRIDE;
-    virtual bool operator!=(const TextTrackCue& cue) const OVERRIDE
-    {
-        return !(*this == cue);
-    }
+    virtual bool isEqual(const TextTrackCue&, CueMatchRules) const OVERRIDE;
 
     virtual TextTrackCue::CueType cueType() const OVERRIDE { return TextTrackCue::Generic; }
 

Modified: trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h (148539 => 148540)


--- trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -27,7 +27,7 @@
 #define InbandTextTrackPrivateClient_h
 
 #include "Color.h"
-#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
 #if ENABLE(VIDEO_TRACK)
@@ -36,20 +36,10 @@
 
 class InbandTextTrackPrivate;
 
-class GenericCueData {
-    WTF_MAKE_NONCOPYABLE(GenericCueData); WTF_MAKE_FAST_ALLOCATED;
+class GenericCueData : public RefCounted<GenericCueData> {
 public:
-    GenericCueData()
-        : m_startTime(0)
-        , m_endTime(0)
-        , m_line(-1)
-        , m_position(-1)
-        , m_size(-1)
-        , m_align(None)
-        , m_baseFontSize(0)
-        , m_relativeFontSize(0)
-    {
-    }
+
+    static PassRefPtr<GenericCueData> create() { return adoptRef(new GenericCueData()); }
     virtual ~GenericCueData() { }
 
     double startTime() const { return m_startTime; }
@@ -97,7 +87,28 @@
     Color backgroundColor() const { return m_backgroundColor; }
     void setBackgroundColor(RGBA32 color) { m_backgroundColor.setRGB(color); }
 
+    enum Status {
+        Uninitialized,
+        Partial,
+        Complete,
+    };
+    Status status() { return m_status; }
+    void setStatus(Status status) { m_status = status; }
+    
 private:
+    GenericCueData()
+        : m_startTime(0)
+        , m_endTime(0)
+        , m_line(-1)
+        , m_position(-1)
+        , m_size(-1)
+        , m_align(None)
+        , m_baseFontSize(0)
+        , m_relativeFontSize(0)
+        , m_status(Uninitialized)
+    {
+    }
+
     double m_startTime;
     double m_endTime;
     String m_id;
@@ -111,14 +122,16 @@
     double m_relativeFontSize;
     Color m_foregroundColor;
     Color m_backgroundColor;
+    Status m_status;
 };
 
 class InbandTextTrackPrivateClient {
 public:
     virtual ~InbandTextTrackPrivateClient() { }
     
-    virtual void addWebVTTCue(InbandTextTrackPrivate*, double /*start*/, double /*end*/, const String& /*id*/, const String& /*content*/, const String& /*settings*/) = 0;
-    virtual void addGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
+    virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) = 0;
+    virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
+    virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp (148539 => 148540)


--- trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -339,25 +339,13 @@
 
         if (m_currentCueEndTime >= m_currentCueStartTime) {
             for (size_t i = 0; i < m_cues.size(); i++) {
-
                 GenericCueData* cueData = m_cues[i].get();
 
-                LOG(Media, "InbandTextTrackPrivateAVF::processCue flushing cue: start=%.2f, end=%.2f, content=\"%s\" \n",
-                    m_currentCueStartTime, m_currentCueEndTime, cueData->content().utf8().data());
-                
-                if (!cueData->content().length())
-                    continue;
-                
-                cueData->setStartTime(m_currentCueStartTime);
                 cueData->setEndTime(m_currentCueEndTime);
-                
-                // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to
-                // set CSS "left".
-                if (cueData->position() >= 0 && cueData->size() > 0)
-                    cueData->setPosition(cueData->position() - cueData->size() / 2);
-                
-                LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position =  %.2f, line =  %.2f", this, cueData->startTime(), cueData->position(), cueData->line());
-                client()->addGenericCue(this, cueData);
+                cueData->setStatus(GenericCueData::Complete);
+
+                LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) -  updating cue: start=%.2f, end=%.2f, content=\"%s\"", this, cueData->startTime(), m_currentCueEndTime, cueData->content().utf8().data());
+                client()->updateGenericCue(this, cueData);
             }
         } else
             LOG(Media, "InbandTextTrackPrivateAVF::processCue negative length cue(s) ignored: start=%.2f, end=%.2f\n", m_currentCueStartTime, m_currentCueEndTime);
@@ -378,9 +366,27 @@
         if (!attributedString || !CFAttributedStringGetLength(attributedString))
             continue;
 
-        m_cues.append(adoptPtr(new GenericCueData));
-        processCueAttributes(attributedString, m_cues[i].get());
+        RefPtr<GenericCueData> cueData = GenericCueData::create();
+        processCueAttributes(attributedString, cueData.get());
+        if (!cueData->content().length())
+            continue;
+
+        m_cues.append(cueData);
+
         m_currentCueStartTime = time;
+        cueData->setStartTime(m_currentCueStartTime);
+        cueData->setEndTime(numeric_limits<double>::infinity()); // duration
+        
+        // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to
+        // set CSS "left".
+        if (cueData->position() >= 0 && cueData->size() > 0)
+            cueData->setPosition(cueData->position() - cueData->size() / 2);
+        
+        LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position =  %.2f, line =  %.2f", this, cueData->startTime(), cueData->position(), cueData->line());
+
+        cueData->setStatus(GenericCueData::Partial);
+        client()->addGenericCue(this, cueData.release());
+
         m_havePartialCue = true;
     }
 }
@@ -396,6 +402,11 @@
     if (m_havePartialCue && !m_currentCueEndTime)
         LOG(Media, "InbandTextTrackPrivateAVF::resetCueValues flushing data for cues: start=%.2f\n", m_currentCueStartTime);
 
+    if (client()) {
+        for (size_t i = 0; i < m_cues.size(); i++)
+            client()->removeGenericCue(this, m_cues[i].get());
+    }
+
     m_cues.resize(0);
     m_havePartialCue = false;
     m_currentCueStartTime = 0;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h (148539 => 148540)


--- trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h	2013-04-16 20:42:49 UTC (rev 148540)
@@ -29,12 +29,11 @@
 #if ENABLE(VIDEO) && ((USE(AVFOUNDATION) && HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)) || PLATFORM(IOS))
 
 #include "InbandTextTrackPrivate.h"
+#include "InbandTextTrackPrivateClient.h"
 #include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
-class GenericCueData;
-
 class AVFInbandTrackParent {
 public:
     virtual ~AVFInbandTrackParent();
@@ -68,7 +67,7 @@
     double m_currentCueStartTime;
     double m_currentCueEndTime;
 
-    Vector<OwnPtr<GenericCueData> > m_cues;
+    Vector<RefPtr<GenericCueData> > m_cues;
 
     AVFInbandTrackParent* m_owner;
     int m_index;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp (148539 => 148540)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2013-04-16 20:22:17 UTC (rev 148539)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2013-04-16 20:42:49 UTC (rev 148540)
@@ -597,11 +597,6 @@
     LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
     UNUSED_PARAM(finished);
 
-#if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
-    if (currentTrack())
-        currentTrack()->resetCueValues();
-#endif
-
     m_seekTo = MediaPlayer::invalidTime();
     updateStates();
     m_player->timeChanged();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to