Changeset 148540 in webkit


Ignore:
Timestamp:
Apr 16, 2013 1:42:49 PM (11 years ago)
Author:
eric.carlson@apple.com
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.

Location:
trunk/Source/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r148539 r148540  
     12013-04-16  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [Mac] in-band cues sometimes displayed late
     4        https://bugs.webkit.org/show_bug.cgi?id=114629
     5
     6        Reviewed by Jer Noble.
     7
     8        No new tests, this deals with a platform-specific issue that is extremely timing dependent.
     9
     10        * html/track/InbandTextTrack.cpp:
     11        (WebCore::TextTrackCueMap::add): New, two way cue data <-> cue map.
     12        (WebCore::TextTrackCueMap::find):
     13        (WebCore::TextTrackCueMap::remove):
     14        (WebCore::InbandTextTrack::updateCueFromCueData): New, update an existing cue. Set cue end time
     15            to video duration if it is unknown.
     16        (WebCore::InbandTextTrack::addGenericCue): Look for existing cues without considering duration
     17            so we can match incomplete cues.
     18        (WebCore::InbandTextTrack::updateGenericCue): New, update an existing cue. This allows us to
     19            add in-band cues as soon as we get them from the media engine and update them as more
     20            information becomes available.
     21        (WebCore::InbandTextTrack::removeGenericCue): New, remove an existing cue. This is necessary
     22            because we never want to keep an incomplete cue when a seek happens.
     23        (WebCore::InbandTextTrack::removeCue): New, base class override so we can keep the two way
     24            map up to date.
     25        * html/track/InbandTextTrack.h:
     26
     27        * html/track/TextTrack.cpp:
     28        (WebCore::TextTrack::addCue): TextTrack::removeCue takes a RefPtr.
     29        (WebCore::TextTrack::removeCue): Take a RefPtr.
     30        (WebCore::TextTrack::hasCue): Allow caller to request match without considering end time.
     31        * html/track/TextTrack.h:
     32
     33        * html/track/TextTrackCue.cpp:
     34        (WebCore::TextTrackCue::TextTrackCue): Initialize m_processingCueChanges.
     35        (WebCore::TextTrackCue::willChange): Renamed from cueWillChange. Use m_processingCueChanges
     36            to avoid thrashing the track when many cue properties will change.
     37        (WebCore::TextTrackCue::didChange): Renamed from cueDidChange. Use m_processingCueChanges
     38            to avoid thrashing the track when many cue properties will change.
     39        (WebCore::TextTrackCue::setId): cueWillChange -> willChange. cueDidChange -> didChange.
     40        (WebCore::TextTrackCue::setStartTime): Ditto.
     41        (WebCore::TextTrackCue::setEndTime): Ditto.
     42        (WebCore::TextTrackCue::setPauseOnExit): Ditto.
     43        (WebCore::TextTrackCue::setVertical): Ditto.
     44        (WebCore::TextTrackCue::setSnapToLines): Ditto.
     45        (WebCore::TextTrackCue::setLine): Ditto.
     46        (WebCore::TextTrackCue::setPosition): Ditto.
     47        (WebCore::TextTrackCue::setSize): Ditto.
     48        (WebCore::TextTrackCue::setAlign): Ditto.
     49        (WebCore::TextTrackCue::setText): Ditto.
     50        (WebCore::TextTrackCue::setRegionId): Ditto.
     51        (WebCore::TextTrackCue::isEqual): Renamed from operator==, take match rules param.
     52        * html/track/TextTrackCue.h:
     53
     54        * html/track/TextTrackCueGeneric.cpp:
     55        (WebCore::TextTrackCueGeneric::isEqual): Renamed from operator==, take match rules param.
     56        * html/track/TextTrackCueGeneric.h:
     57
     58        * platform/graphics/InbandTextTrackPrivateClient.h: Make GenericCueData refcounted.
     59        (WebCore::GenericCueData::create): New.
     60        (WebCore::GenericCueData::status): Ditto.
     61        (WebCore::GenericCueData::setStatus): Ditto.
     62        (WebCore::GenericCueData::GenericCueData):
     63
     64        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp:
     65        (WebCore::InbandTextTrackPrivateAVF::processCue): Add cues as soon as we get them from the media
     66            engine, update duration once we know it.
     67        (WebCore::InbandTextTrackPrivateAVF::resetCueValues): Tell the client to remove all incomplete
     68            cues we have delivered.
     69        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h:
     70
     71        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
     72        (WebCore::MediaPlayerPrivateAVFoundation::seekCompleted): Do not flush cues when seek completes,
     73            we did that when the seek started and cues can be delivered before we get the the
     74            seek completed  notification.
     75
    1762013-04-16  James Craig  <james@cookiecrook.com>
    277
  • trunk/Source/WebCore/html/track/InbandTextTrack.cpp

    r148285 r148540  
    3333#include "Event.h"
    3434#include "ExceptionCodePlaceholder.h"
     35#include "HTMLMediaElement.h"
    3536#include "InbandTextTrackPrivate.h"
    3637#include "Logging.h"
    37 #include "MediaPlayer.h"
    3838#include "TextTrackCueGeneric.h"
    3939#include "TextTrackCueList.h"
     
    4242
    4343namespace WebCore {
     44
     45void TextTrackCueMap::add(GenericCueData* cueData, TextTrackCueGeneric* cue)
     46{
     47    m_dataToCueMap.add(cueData, cue);
     48    m_cueToDataMap.add(cue, cueData);
     49}
     50
     51PassRefPtr<TextTrackCueGeneric> TextTrackCueMap::find(GenericCueData* cueData)
     52{
     53    GenericCueDataToCueMap::iterator iter = m_dataToCueMap.find(cueData);
     54    if (iter == m_dataToCueMap.end())
     55        return 0;
     56   
     57    return iter->value;
     58}
     59
     60PassRefPtr<GenericCueData> TextTrackCueMap::find(TextTrackCueGeneric* cue)
     61{
     62    GenericCueToCueDataMap::iterator iter = m_cueToDataMap.find(cue);
     63    if (iter == m_cueToDataMap.end())
     64        return 0;
     65   
     66    return iter->value;
     67}
     68
     69void TextTrackCueMap::remove(GenericCueData* cueData)
     70{
     71    RefPtr<TextTrackCueGeneric> cue = find(cueData);
     72
     73    if (cue)
     74        m_cueToDataMap.remove(cue);
     75    m_dataToCueMap.remove(cueData);
     76}
     77
     78void TextTrackCueMap::remove(TextTrackCueGeneric* cue)
     79{
     80    RefPtr<GenericCueData> cueData = find(cue);
     81
     82    if (cueData)
     83        m_dataToCueMap.remove(cueData);
     84    m_cueToDataMap.remove(cue);
     85}
     86
    4487
    4588PassRefPtr<InbandTextTrack> InbandTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
     
    137180}
    138181
    139 void InbandTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, GenericCueData* cueData)
    140 {
    141     UNUSED_PARAM(trackPrivate);
    142     ASSERT(trackPrivate == m_private);
    143 
    144     RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
    145 
     182void InbandTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, GenericCueData* cueData)
     183{
     184    cue->willChange();
     185
     186    cue->setStartTime(cueData->startTime(), IGNORE_EXCEPTION);
     187    double endTime = cueData->endTime();
     188    if (std::isinf(endTime) && mediaElement())
     189        endTime = mediaElement()->duration();
     190    cue->setEndTime(endTime, IGNORE_EXCEPTION);
     191    cue->setText(cueData->content());
    146192    cue->setId(cueData->id());
    147193    cue->setBaseFontSizeRelativeToVideoHeight(cueData->baseFontSize());
     
    168214    cue->setSnapToLines(false);
    169215
    170     if (hasCue(cue.get())) {
    171         LOG(Media, "InbandTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n",
    172             cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
     216    cue->didChange();
     217}
     218   
     219void InbandTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, PassRefPtr<GenericCueData> prpCueData)
     220{
     221    UNUSED_PARAM(trackPrivate);
     222    ASSERT(trackPrivate == m_private);
     223
     224    RefPtr<GenericCueData> cueData = prpCueData;
     225    if (m_cueMap.find(cueData.get()))
     226        return;
     227
     228    RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
     229    updateCueFromCueData(cue.get(), cueData.get());
     230    if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
     231        LOG(Media, "InbandTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
    173232        return;
    174233    }
    175234
     235    m_cueMap.add(cueData.get(), cue.get());
     236
    176237    addCue(cue);
    177238}
    178239
    179 void InbandTextTrack::addWebVTTCue(InbandTextTrackPrivate* trackPrivate, double start, double end, const String& id, const String& content, const String& settings)
    180 {
    181     UNUSED_PARAM(trackPrivate);
    182     ASSERT(trackPrivate == m_private);
    183 
    184     RefPtr<TextTrackCue> cue = TextTrackCue::create(scriptExecutionContext(), start, end, content);
    185     cue->setId(id);
    186     cue->setCueSettings(settings);
    187    
    188     if (hasCue(cue.get()))
     240void InbandTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
     241{
     242    RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
     243    if (!cue)
    189244        return;
    190245
    191     addCue(cue);
    192 }
    193 
     246    updateCueFromCueData(cue.get(), cueData);
     247   
     248    if (cueData->status() == GenericCueData::Complete)
     249        m_cueMap.remove(cueData);
     250}
     251
     252void InbandTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
     253{
     254    RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
     255    if (cue)
     256        removeCue(cue.get(), IGNORE_EXCEPTION);
     257    else
     258        m_cueMap.remove(cueData);
     259}
     260
     261void InbandTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
     262{
     263    m_cueMap.remove(static_cast<TextTrackCueGeneric*>(cue));
     264    TextTrack::removeCue(cue, ec);
     265}
     266   
    194267} // namespace WebCore
    195268
  • trunk/Source/WebCore/html/track/InbandTextTrack.h

    r146380 r148540  
    3232#include "InbandTextTrackPrivateClient.h"
    3333#include "TextTrack.h"
     34#include "TextTrackCueGeneric.h"
    3435#include <wtf/RefPtr.h>
    3536
     
    3839class Document;
    3940class InbandTextTrackPrivate;
    40 class MediaPlayer;
    4141class TextTrackCue;
     42
     43class TextTrackCueMap {
     44public:
     45    TextTrackCueMap() { }
     46    virtual ~TextTrackCueMap() { }
     47
     48    void add(GenericCueData*, TextTrackCueGeneric*);
     49
     50    void remove(GenericCueData*);
     51    void remove(TextTrackCueGeneric*);
     52   
     53    PassRefPtr<GenericCueData> find(TextTrackCueGeneric*);
     54    PassRefPtr<TextTrackCueGeneric> find(GenericCueData*);
     55   
     56private:
     57    typedef HashMap<RefPtr<TextTrackCueGeneric>, RefPtr<GenericCueData> > GenericCueToCueDataMap;
     58    typedef HashMap<RefPtr<GenericCueData>, RefPtr<TextTrackCueGeneric> > GenericCueDataToCueMap;
     59   
     60    GenericCueToCueDataMap m_cueToDataMap;
     61    GenericCueDataToCueMap m_dataToCueMap;
     62};
    4263
    4364class InbandTextTrack : public TextTrack, public InbandTextTrackPrivateClient {
     
    5677    InbandTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
    5778
    58     virtual void addGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
    59     virtual void addWebVTTCue(InbandTextTrackPrivate*, double, double, const String&, const String&, const String&) OVERRIDE;
     79    virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) OVERRIDE;
     80    virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
     81    virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) OVERRIDE;
     82    virtual void removeCue(TextTrackCue*, ExceptionCode&) OVERRIDE;
     83
     84    PassRefPtr<TextTrackCueGeneric> createCue(PassRefPtr<GenericCueData>);
     85    void updateCueFromCueData(TextTrackCueGeneric*, GenericCueData*);
    6086
    6187#if USE(PLATFORM_TEXT_TRACK_MENU)
     
    6389#endif
    6490
     91    TextTrackCueMap m_cueMap;
    6592    RefPtr<InbandTextTrackPrivate> m_private;
    6693};
  • trunk/Source/WebCore/html/track/TextTrack.cpp

    r148305 r148540  
    467467}
    468468
    469 bool TextTrack::hasCue(TextTrackCue* cue)
     469bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
    470470{
    471471    if (cue->startTime() < 0 || cue->endTime() < 0)
     
    506506                    return false;
    507507
    508                 if (*existingCue != *cue)
     508                if (!existingCue->isEqual(*cue, match))
    509509                    continue;
    510510               
     
    515515        size_t index = (searchStart + searchEnd) / 2;
    516516        existingCue = m_cues->item(index);
    517         if (cue->startTime() < existingCue->startTime() || (cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
     517        if (cue->startTime() < existingCue->startTime() || (match != TextTrackCue::IgnoreDuration && cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
    518518            searchEnd = index;
    519519        else
  • trunk/Source/WebCore/html/track/TextTrack.h

    r148305 r148540  
    3131
    3232#include "ExceptionCode.h"
     33#include "TextTrackCue.h"
    3334#include "TrackBase.h"
    3435#include <wtf/PassOwnPtr.h>
     
    4445class ScriptExecutionContext;
    4546class TextTrack;
    46 class TextTrackCue;
    4747class TextTrackCueList;
    4848#if ENABLE(WEBVTT_REGIONS)
     
    109109
    110110    void addCue(PassRefPtr<TextTrackCue>);
    111     void removeCue(TextTrackCue*, ExceptionCode&);
    112     bool hasCue(TextTrackCue*);
     111    virtual void removeCue(TextTrackCue*, ExceptionCode&);
     112
     113    bool hasCue(TextTrackCue*, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
    113114
    114115#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
  • trunk/Source/WebCore/html/track/TextTrackCue.cpp

    r148099 r148540  
    4141#include "Event.h"
    4242#include "HTMLDivElement.h"
    43 #include "HTMLMediaElement.h"
    4443#include "HTMLSpanElement.h"
    4544#include "Logging.h"
     
    195194    , m_cueSize(100)
    196195    , m_cueIndex(invalidCueIndex)
     196    , m_processingCueChanges(0)
    197197    , m_writingDirection(Horizontal)
    198198    , m_cueAlignment(Middle)
     
    236236}
    237237
    238 void TextTrackCue::cueWillChange()
    239 {
     238void TextTrackCue::willChange()
     239{
     240    if (++m_processingCueChanges > 1)
     241        return;
     242
    240243    if (m_track)
    241244        m_track->cueWillChange(this);
    242245}
    243246
    244 void TextTrackCue::cueDidChange()
    245 {
     247void TextTrackCue::didChange()
     248{
     249    ASSERT(m_processingCueChanges);
     250    if (--m_processingCueChanges)
     251        return;
     252
    246253    if (m_track)
    247254        m_track->cueDidChange(this);
     
    265272        return;
    266273
    267     cueWillChange();
     274    willChange();
    268275    m_id = id;
    269     cueDidChange();
     276    didChange();
    270277}
    271278
     
    281288    if (m_startTime == value || value < 0)
    282289        return;
    283    
    284     cueWillChange();
     290
     291    willChange();
    285292    m_startTime = value;
    286     cueDidChange();
     293    didChange();
    287294}
    288295   
     
    298305    if (m_endTime == value || value < 0)
    299306        return;
    300    
    301     cueWillChange();
     307
     308    willChange();
    302309    m_endTime = value;
    303     cueDidChange();
     310    didChange();
    304311}
    305312   
     
    309316        return;
    310317   
    311     cueWillChange();
    312318    m_pauseOnExit = value;
    313     cueDidChange();
    314319}
    315320
     
    350355        return;
    351356
    352     cueWillChange();
     357    willChange();
    353358    m_writingDirection = direction;
    354     cueDidChange();
     359    didChange();
    355360}
    356361
     
    360365        return;
    361366   
    362     cueWillChange();
     367    willChange();
    363368    m_snapToLines = value;
    364     cueDidChange();
     369    didChange();
    365370}
    366371
     
    379384        return;
    380385
    381     cueWillChange();
     386    willChange();
    382387    m_linePosition = position;
    383388    m_computedLinePosition = calculateComputedLinePosition();
    384     cueDidChange();
     389    didChange();
    385390}
    386391
     
    399404        return;
    400405   
    401     cueWillChange();
     406    willChange();
    402407    m_textPosition = position;
    403     cueDidChange();
     408    didChange();
    404409}
    405410
     
    418423        return;
    419424   
    420     cueWillChange();
     425    willChange();
    421426    m_cueSize = size;
    422     cueDidChange();
     427    didChange();
    423428}
    424429
     
    459464        return;
    460465
    461     cueWillChange();
     466    willChange();
    462467    m_cueAlignment = alignment;
    463     cueDidChange();
     468    didChange();
    464469}
    465470   
     
    469474        return;
    470475   
    471     cueWillChange();
     476    willChange();
    472477    // Clear the document fragment but don't bother to create it again just yet as we can do that
    473478    // when it is requested.
    474479    m_webVTTNodeTree = 0;
    475480    m_content = text;
    476     cueDidChange();
     481    didChange();
    477482}
    478483
     
    542547        return;
    543548
    544     cueWillChange();
     549    willChange();
    545550    m_regionId = regionId;
    546     cueDidChange();
     551    didChange();
    547552}
    548553#endif
     
    11541159}
    11551160
    1156 bool TextTrackCue::operator==(const TextTrackCue& cue) const
     1161bool TextTrackCue::isEqual(const TextTrackCue& cue, CueMatchRules match) const
    11571162{
    11581163    if (cueType() != cue.cueType())
    11591164        return false;
    1160 
    1161     if (m_endTime != cue.endTime())
     1165   
     1166    if (match != IgnoreDuration && m_endTime != cue.endTime())
    11621167        return false;
    11631168    if (m_startTime != cue.startTime())
     
    11801185    return true;
    11811186}
    1182 
    11831187void TextTrackCue::setFontSize(int fontSize, const IntSize&, bool important)
    11841188{
  • trunk/Source/WebCore/html/track/TextTrackCue.h

    r148099 r148540  
    3838#include "HTMLDivElement.h"
    3939#include "HTMLElement.h"
    40 #include "TextTrack.h"
    4140#include <wtf/PassOwnPtr.h>
    4241#include <wtf/RefCounted.h>
     
    180179    virtual void setFontSize(int, const IntSize&, bool important);
    181180
    182     virtual bool operator==(const TextTrackCue&) const;
    183     virtual bool operator!=(const TextTrackCue& cue) const
    184     {
    185         return !(*this == cue);
    186     }
    187    
     181    enum CueMatchRules {
     182        MatchAllFields,
     183        IgnoreDuration,
     184    };
     185    virtual bool isEqual(const TextTrackCue&, CueMatchRules) const;
     186
    188187    enum CueType {
    189188        Generic,
     
    192191    virtual CueType cueType() const { return WebVTT; }
    193192
     193    void willChange();
     194    void didChange();
     195   
    194196    DEFINE_ATTRIBUTE_EVENT_LISTENER(enter);
    195197    DEFINE_ATTRIBUTE_EVENT_LISTENER(exit);
     
    218220    void determineTextDirection();
    219221    void calculateDisplayParameters();
    220 
    221     void cueWillChange();
    222     void cueDidChange();
    223222
    224223    virtual void refEventTarget() { ref(); }
     
    248247    int m_cueSize;
    249248    int m_cueIndex;
     249    int m_processingCueChanges;
    250250
    251251    WritingDirection m_writingDirection;
  • trunk/Source/WebCore/html/track/TextTrackCueGeneric.cpp

    r148058 r148540  
    152152}
    153153   
    154 bool TextTrackCueGeneric::operator==(const TextTrackCue& cue) const
     154bool TextTrackCueGeneric::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
    155155{
    156156    if (cue.cueType() != TextTrackCue::Generic)
     
    170170        return false;
    171171
    172     return TextTrackCue::operator==(cue);
     172    return TextTrackCue::isEqual(cue, match);
    173173}
    174174   
  • trunk/Source/WebCore/html/track/TextTrackCueGeneric.h

    r148050 r148540  
    7171    virtual void setFontSize(int, const IntSize&, bool important) OVERRIDE;
    7272
    73     virtual bool operator==(const TextTrackCue&) const OVERRIDE;
    74     virtual bool operator!=(const TextTrackCue& cue) const OVERRIDE
    75     {
    76         return !(*this == cue);
    77     }
     73    virtual bool isEqual(const TextTrackCue&, CueMatchRules) const OVERRIDE;
    7874
    7975    virtual TextTrackCue::CueType cueType() const OVERRIDE { return TextTrackCue::Generic; }
  • trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h

    r142349 r148540  
    2828
    2929#include "Color.h"
    30 #include <wtf/Noncopyable.h>
     30#include <wtf/RefCounted.h>
    3131#include <wtf/text/WTFString.h>
    3232
     
    3737class InbandTextTrackPrivate;
    3838
    39 class GenericCueData {
    40     WTF_MAKE_NONCOPYABLE(GenericCueData); WTF_MAKE_FAST_ALLOCATED;
     39class GenericCueData : public RefCounted<GenericCueData> {
    4140public:
    42     GenericCueData()
    43         : m_startTime(0)
    44         , m_endTime(0)
    45         , m_line(-1)
    46         , m_position(-1)
    47         , m_size(-1)
    48         , m_align(None)
    49         , m_baseFontSize(0)
    50         , m_relativeFontSize(0)
    51     {
    52     }
     41
     42    static PassRefPtr<GenericCueData> create() { return adoptRef(new GenericCueData()); }
    5343    virtual ~GenericCueData() { }
    5444
     
    9888    void setBackgroundColor(RGBA32 color) { m_backgroundColor.setRGB(color); }
    9989
     90    enum Status {
     91        Uninitialized,
     92        Partial,
     93        Complete,
     94    };
     95    Status status() { return m_status; }
     96    void setStatus(Status status) { m_status = status; }
     97   
    10098private:
     99    GenericCueData()
     100        : m_startTime(0)
     101        , m_endTime(0)
     102        , m_line(-1)
     103        , m_position(-1)
     104        , m_size(-1)
     105        , m_align(None)
     106        , m_baseFontSize(0)
     107        , m_relativeFontSize(0)
     108        , m_status(Uninitialized)
     109    {
     110    }
     111
    101112    double m_startTime;
    102113    double m_endTime;
     
    112123    Color m_foregroundColor;
    113124    Color m_backgroundColor;
     125    Status m_status;
    114126};
    115127
     
    118130    virtual ~InbandTextTrackPrivateClient() { }
    119131   
    120     virtual void addWebVTTCue(InbandTextTrackPrivate*, double /*start*/, double /*end*/, const String& /*id*/, const String& /*content*/, const String& /*settings*/) = 0;
    121     virtual void addGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
     132    virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) = 0;
     133    virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
     134    virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
    122135};
    123136
  • trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.cpp

    r148285 r148540  
    340340        if (m_currentCueEndTime >= m_currentCueStartTime) {
    341341            for (size_t i = 0; i < m_cues.size(); i++) {
    342 
    343342                GenericCueData* cueData = m_cues[i].get();
    344343
    345                 LOG(Media, "InbandTextTrackPrivateAVF::processCue flushing cue: start=%.2f, end=%.2f, content=\"%s\" \n",
    346                     m_currentCueStartTime, m_currentCueEndTime, cueData->content().utf8().data());
    347                
    348                 if (!cueData->content().length())
    349                     continue;
    350                
    351                 cueData->setStartTime(m_currentCueStartTime);
    352344                cueData->setEndTime(m_currentCueEndTime);
    353                
    354                 // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to
    355                 // set CSS "left".
    356                 if (cueData->position() >= 0 && cueData->size() > 0)
    357                     cueData->setPosition(cueData->position() - cueData->size() / 2);
    358                
    359                 LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position =  %.2f, line =  %.2f", this, cueData->startTime(), cueData->position(), cueData->line());
    360                 client()->addGenericCue(this, cueData);
     345                cueData->setStatus(GenericCueData::Complete);
     346
     347                LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) -  updating cue: start=%.2f, end=%.2f, content=\"%s\"", this, cueData->startTime(), m_currentCueEndTime, cueData->content().utf8().data());
     348                client()->updateGenericCue(this, cueData);
    361349            }
    362350        } else
     
    379367            continue;
    380368
    381         m_cues.append(adoptPtr(new GenericCueData));
    382         processCueAttributes(attributedString, m_cues[i].get());
     369        RefPtr<GenericCueData> cueData = GenericCueData::create();
     370        processCueAttributes(attributedString, cueData.get());
     371        if (!cueData->content().length())
     372            continue;
     373
     374        m_cues.append(cueData);
     375
    383376        m_currentCueStartTime = time;
     377        cueData->setStartTime(m_currentCueStartTime);
     378        cueData->setEndTime(numeric_limits<double>::infinity()); // duration
     379       
     380        // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to
     381        // set CSS "left".
     382        if (cueData->position() >= 0 && cueData->size() > 0)
     383            cueData->setPosition(cueData->position() - cueData->size() / 2);
     384       
     385        LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position =  %.2f, line =  %.2f", this, cueData->startTime(), cueData->position(), cueData->line());
     386
     387        cueData->setStatus(GenericCueData::Partial);
     388        client()->addGenericCue(this, cueData.release());
     389
    384390        m_havePartialCue = true;
    385391    }
     
    396402    if (m_havePartialCue && !m_currentCueEndTime)
    397403        LOG(Media, "InbandTextTrackPrivateAVF::resetCueValues flushing data for cues: start=%.2f\n", m_currentCueStartTime);
     404
     405    if (client()) {
     406        for (size_t i = 0; i < m_cues.size(); i++)
     407            client()->removeGenericCue(this, m_cues[i].get());
     408    }
    398409
    399410    m_cues.resize(0);
  • trunk/Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h

    r145326 r148540  
    3030
    3131#include "InbandTextTrackPrivate.h"
     32#include "InbandTextTrackPrivateClient.h"
    3233#include <wtf/text/StringBuilder.h>
    3334
    3435namespace WebCore {
    35 
    36 class GenericCueData;
    3736
    3837class AVFInbandTrackParent {
     
    6968    double m_currentCueEndTime;
    7069
    71     Vector<OwnPtr<GenericCueData> > m_cues;
     70    Vector<RefPtr<GenericCueData> > m_cues;
    7271
    7372    AVFInbandTrackParent* m_owner;
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp

    r148291 r148540  
    598598    UNUSED_PARAM(finished);
    599599
    600 #if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
    601     if (currentTrack())
    602         currentTrack()->resetCueValues();
    603 #endif
    604 
    605600    m_seekTo = MediaPlayer::invalidTime();
    606601    updateStates();
Note: See TracChangeset for help on using the changeset viewer.