Title: [149187] trunk/Source/WebCore
Revision
149187
Author
[email protected]
Date
2013-04-26 08:17:59 -0700 (Fri, 26 Apr 2013)

Log Message

[Mac] in-band cues sometimes have incorrect duration
https://bugs.webkit.org/show_bug.cgi?id=115200

Reviewed by Jer Noble.

No new tests, this is not possible to test in DRT.

* html/track/InbandTextTrack.cpp:
(WebCore::InbandTextTrack::addGenericCue): Don't add completed cues to the map.
(WebCore::InbandTextTrack::removeGenericCue): Log when a cue is removed from the track.

* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
(WebCore::InbandTextTrackPrivateAVF::InbandTextTrackPrivateAVF): Initialize m_pendingCueStatus.
(WebCore::InbandTextTrackPrivateAVF::processCue): Never call update() on a cue that is delivered
    while seeking.
(WebCore::InbandTextTrackPrivateAVF::beginSeeking): Flush all incomplete cues, remember that
    we are seeking.
(WebCore::InbandTextTrackPrivateAVF::resetCueValues):
* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h:

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::seek): Call track->beginSeeking() instead of resetCueValues().
(WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Call track->endSeeking().

* platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm:
(WebCore::InbandTextTrackPrivateAVFObjC::kind): Include class name in Kind enum values to
    avoid compile error.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (149186 => 149187)


--- trunk/Source/WebCore/ChangeLog	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/ChangeLog	2013-04-26 15:17:59 UTC (rev 149187)
@@ -1,3 +1,33 @@
+2013-04-26  Eric Carlson  <[email protected]>
+
+        [Mac] in-band cues sometimes have incorrect duration
+        https://bugs.webkit.org/show_bug.cgi?id=115200
+
+        Reviewed by Jer Noble.
+
+        No new tests, this is not possible to test in DRT.
+
+        * html/track/InbandTextTrack.cpp:
+        (WebCore::InbandTextTrack::addGenericCue): Don't add completed cues to the map.
+        (WebCore::InbandTextTrack::removeGenericCue): Log when a cue is removed from the track.
+
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
+        (WebCore::InbandTextTrackPrivateAVF::InbandTextTrackPrivateAVF): Initialize m_pendingCueStatus.
+        (WebCore::InbandTextTrackPrivateAVF::processCue): Never call update() on a cue that is delivered
+            while seeking.
+        (WebCore::InbandTextTrackPrivateAVF::beginSeeking): Flush all incomplete cues, remember that 
+            we are seeking.
+        (WebCore::InbandTextTrackPrivateAVF::resetCueValues): 
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h:
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::seek): Call track->beginSeeking() instead of resetCueValues().
+        (WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Call track->endSeeking().
+
+        * platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm:
+        (WebCore::InbandTextTrackPrivateAVFObjC::kind): Include class name in Kind enum values to 
+            avoid compile error.
+
 2013-04-26  Andreas Kling  <[email protected]>
 
         Remove wxWebKit from WebCore.

Modified: trunk/Source/WebCore/html/track/InbandTextTrack.cpp (149186 => 149187)


--- trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.cpp	2013-04-26 15:17:59 UTC (rev 149187)
@@ -232,7 +232,8 @@
         return;
     }
 
-    m_cueMap.add(cueData.get(), cue.get());
+    if (cueData->status() != GenericCueData::Complete)
+        m_cueMap.add(cueData.get(), cue.get());
 
     addCue(cue);
 }
@@ -252,9 +253,10 @@
 void InbandTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
 {
     RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
-    if (cue)
+    if (cue) {
+        LOG(Media, "InbandTextTrack::removeGenericCue removing cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
         removeCue(cue.get(), IGNORE_EXCEPTION);
-    else
+    } else
         m_cueMap.remove(cueData);
 }
 

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp	2013-04-26 15:17:59 UTC (rev 149187)
@@ -89,9 +89,10 @@
 
 InbandTextTrackPrivateAVF::InbandTextTrackPrivateAVF(AVFInbandTrackParent* owner)
     : m_owner(owner)
+    , m_pendingCueStatus(None)
     , m_index(0)
-    , m_havePartialCue(false)
     , m_hasBeenReported(false)
+    , m_seeking(false)
 {
 }
 
@@ -332,8 +333,10 @@
 {
     if (!client())
         return;
-    
-    if (m_havePartialCue) {
+
+    LOG(Media, "InbandTextTrackPrivateAVF::processCue - %li cues at time %.2f\n", CFArrayGetCount(attributedStrings), time);
+
+    if (m_pendingCueStatus != None) {
         // Cues do not have an explicit duration, they are displayed until the next "cue" (which might be empty) is emitted.
         m_currentCueEndTime = time;
 
@@ -341,11 +344,17 @@
             for (size_t i = 0; i < m_cues.size(); i++) {
                 GenericCueData* cueData = m_cues[i].get();
 
-                cueData->setEndTime(m_currentCueEndTime);
-                cueData->setStatus(GenericCueData::Complete);
+                if (m_pendingCueStatus == Valid) {
+                    cueData->setEndTime(m_currentCueEndTime);
+                    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);
+                    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 {
+                    // We have to assume that the implicit duration is invalid for cues delivered during a seek because the AVF decode pipeline may not
+                    // see every cue, so DO NOT update cue duration while seeking.
+                    LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - ignoring cue delivered during seek: start=%.2f, end=%.2f, content=\"%s\"", this, cueData->startTime(), m_currentCueEndTime, cueData->content().utf8().data());
+                }
             }
         } else
             LOG(Media, "InbandTextTrackPrivateAVF::processCue negative length cue(s) ignored: start=%.2f, end=%.2f\n", m_currentCueStartTime, m_currentCueEndTime);
@@ -375,7 +384,7 @@
 
         m_currentCueStartTime = time;
         cueData->setStartTime(m_currentCueStartTime);
-        cueData->setEndTime(numeric_limits<double>::infinity()); // duration
+        cueData->setEndTime(numeric_limits<double>::infinity());
         
         // 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".
@@ -387,10 +396,19 @@
         cueData->setStatus(GenericCueData::Partial);
         client()->addGenericCue(this, cueData.release());
 
-        m_havePartialCue = true;
+        m_pendingCueStatus = seeking() ? DeliveredDuringSeek : Valid;
     }
 }
 
+void InbandTextTrackPrivateAVF::beginSeeking()
+{
+    // Forget any partially accumulated cue data as the seek could be to a time outside of the cue's
+    // range, which will mean that the next cue delivered will result in the current cue getting the
+    // incorrect duration.
+    resetCueValues();
+    m_seeking = true;
+}
+
 void InbandTextTrackPrivateAVF::disconnect()
 {
     m_owner = 0;
@@ -399,7 +417,7 @@
 
 void InbandTextTrackPrivateAVF::resetCueValues()
 {
-    if (m_havePartialCue && !m_currentCueEndTime)
+    if (m_currentCueEndTime && m_cues.size())
         LOG(Media, "InbandTextTrackPrivateAVF::resetCueValues flushing data for cues: start=%.2f\n", m_currentCueStartTime);
 
     if (client()) {
@@ -408,7 +426,7 @@
     }
 
     m_cues.resize(0);
-    m_havePartialCue = false;
+    m_pendingCueStatus = None;
     m_currentCueStartTime = 0;
     m_currentCueEndTime = 0;
 }

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h	2013-04-26 15:17:59 UTC (rev 149187)
@@ -59,6 +59,10 @@
     void processCue(CFArrayRef, double);
     void resetCueValues();
 
+    void beginSeeking();
+    void endSeeking() { m_seeking = false; }
+    bool seeking() const { return m_seeking; }
+
 protected:
     InbandTextTrackPrivateAVF(AVFInbandTrackParent*);
 
@@ -68,11 +72,18 @@
     double m_currentCueEndTime;
 
     Vector<RefPtr<GenericCueData> > m_cues;
+    AVFInbandTrackParent* m_owner;
 
-    AVFInbandTrackParent* m_owner;
+    enum PendingCueStatus {
+        None,
+        DeliveredDuringSeek,
+        Valid
+    };
+    PendingCueStatus m_pendingCueStatus;
+
     int m_index;
-    bool m_havePartialCue;
     bool m_hasBeenReported;
+    bool m_seeking;
 };
 
 } // namespace WebCore

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2013-04-26 15:17:59 UTC (rev 149187)
@@ -268,11 +268,8 @@
         return;
 
 #if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
-    // Forget any partially accumulated cue data as the seek could be to a time outside of the cue's
-    // range, which will mean that the next cue delivered will result in the current cue getting the
-    // incorrect duration.
     if (currentTrack())
-        currentTrack()->resetCueValues();
+        currentTrack()->beginSeeking();
 #endif
     
     LOG(Media, "MediaPlayerPrivateAVFoundation::seek(%p) - seeking to %f", this, time);
@@ -597,6 +594,11 @@
     LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
     UNUSED_PARAM(finished);
 
+#if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
+    if (currentTrack())
+        currentTrack()->endSeeking();
+#endif
+
     m_seekTo = MediaPlayer::invalidTime();
     updateStates();
     m_player->timeChanged();

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm (149186 => 149187)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm	2013-04-26 15:14:59 UTC (rev 149186)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm	2013-04-26 15:17:59 UTC (rev 149187)
@@ -96,28 +96,28 @@
 InbandTextTrackPrivate::Kind InbandTextTrackPrivateAVFObjC::kind() const
 {
     if (!m_mediaSelectionOption)
-        return None;
+        return InbandTextTrackPrivate::None;
 
     NSString *mediaType = [m_mediaSelectionOption mediaType];
     
     if ([mediaType isEqualToString:AVMediaTypeClosedCaption])
-        return Captions;
+        return InbandTextTrackPrivate::Captions;
     if ([mediaType isEqualToString:AVMediaTypeSubtitle]) {
 
         if ([m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicContainsOnlyForcedSubtitles])
-            return Forced;
+            return InbandTextTrackPrivate::Forced;
 
         // An "SDH" track is a subtitle track created for the deaf or hard-of-hearing. "captions" in WebVTT are
         // "labeled as appropriate for the hard-of-hearing", so tag SDH sutitles as "captions".
         if ([m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicTranscribesSpokenDialogForAccessibility])
-            return Captions;
+            return InbandTextTrackPrivate::Captions;
         if ([m_mediaSelectionOption hasMediaCharacteristic:AVMediaCharacteristicDescribesMusicAndSoundForAccessibility])
-            return Captions;
+            return InbandTextTrackPrivate::Captions;
         
-        return Subtitles;
+        return InbandTextTrackPrivate::Subtitles;
     }
 
-    return Captions;
+    return InbandTextTrackPrivate::Captions;
 }
 
 bool InbandTextTrackPrivateAVFObjC::isClosedCaptions() const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to