Changeset 146647 in webkit


Ignore:
Timestamp:
Mar 22, 2013 1:24:35 PM (11 years ago)
Author:
eric.carlson@apple.com
Message:

Cleanup text track selection logic
https://bugs.webkit.org/show_bug.cgi?id=113062

Reviewed by Jer Noble.

No new tests, covered by existing tests.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::userIsInterestedInThisTrackKind): Remove.
(WebCore::HTMLMediaElement::configureTextTrackGroup): Don't look at track attributes directly,

use captionPreferences->textTrackSelectionScore to calculate track rank.

(WebCore::HTMLMediaElement::setClosedCaptionsVisible): Set m_processingPreferenceChange here

instead of in captionPreferencesChanged.

(WebCore::HTMLMediaElement::captionPreferencesChanged): Don't suppress calls to setClosedCaptionsVisible,

existing code already makes sure we don't do unnecessary work.

  • html/HTMLMediaElement.h:
  • html/shadow/MediaControlElements.cpp:

(WebCore::MediaControlTextTrackContainerElement::updateDisplay): Drive by cleanup, don't

process inactive cues.

  • html/shadow/MediaControlsApple.cpp:

(WebCore::MediaControlsApple::changedClosedCaptionsVisibility): Call resetTrackListMenu instead

of updateDisplay so we only mark the menu as needing a recalculation and do the work when
it is displayed.

  • page/CaptionUserPreferences.cpp:

(WebCore::CaptionUserPreferences::shouldShowCaptions): When in testing mode, return true if

the caption or subtitle preference has been set.

(WebCore::CaptionUserPreferences::setShouldShowCaptions): In testing mode, clear the caption

and subtitle preference when passed false.

(WebCore::CaptionUserPreferences::textTrackSelectionScore): Calculate the track score based on

track type preference and preferred language.

(WebCore::CaptionUserPreferences::textTrackLanguageSelectionScore): Score a track according to

the language presence and position in the preferred languages list.

  • page/CaptionUserPreferences.h:
  • page/CaptionUserPreferencesMac.h:
  • page/CaptionUserPreferencesMac.mm:

(WebCore::CaptionUserPreferencesMac::textTrackSelectionScore): Calculate track language score

according to user preferences.

  • platform/Language.cpp:

(WebCore::indexOfBestMatchingLanguageInList): Repurposed the static bestMatchingLanguage

function to return the location of a language in a Vector.

(WebCore::preferredLanguageFromList): Removed.

  • platform/Language.h:
Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r146646 r146647  
     12013-03-22  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Cleanup text track selection logic
     4        https://bugs.webkit.org/show_bug.cgi?id=113062
     5
     6        Reviewed by Jer Noble.
     7
     8        No new tests, covered by existing tests.
     9
     10        * html/HTMLMediaElement.cpp:
     11        (WebCore::HTMLMediaElement::userIsInterestedInThisTrackKind): Remove.
     12        (WebCore::HTMLMediaElement::configureTextTrackGroup): Don't look at track attributes directly,
     13            use captionPreferences->textTrackSelectionScore to calculate track rank.
     14        (WebCore::HTMLMediaElement::setClosedCaptionsVisible): Set m_processingPreferenceChange here
     15            instead of in captionPreferencesChanged.
     16        (WebCore::HTMLMediaElement::captionPreferencesChanged): Don't suppress calls to setClosedCaptionsVisible,
     17            existing code already makes sure we don't do unnecessary work.
     18        * html/HTMLMediaElement.h:
     19
     20        * html/shadow/MediaControlElements.cpp:
     21        (WebCore::MediaControlTextTrackContainerElement::updateDisplay): Drive by cleanup, don't
     22            process inactive cues.
     23
     24        * html/shadow/MediaControlsApple.cpp:
     25        (WebCore::MediaControlsApple::changedClosedCaptionsVisibility): Call resetTrackListMenu instead
     26            of updateDisplay so we only mark the menu as needing a recalculation and do the work when
     27            it is displayed.
     28
     29        * page/CaptionUserPreferences.cpp:
     30        (WebCore::CaptionUserPreferences::shouldShowCaptions): When in testing mode, return true if
     31            the caption or subtitle preference has been set.
     32        (WebCore::CaptionUserPreferences::setShouldShowCaptions): In testing mode, clear the caption
     33            and subtitle preference when passed false.
     34        (WebCore::CaptionUserPreferences::textTrackSelectionScore): Calculate the track score based on
     35            track type preference and preferred language.
     36        (WebCore::CaptionUserPreferences::textTrackLanguageSelectionScore): Score a track according to
     37            the language presence and position in the preferred languages list.
     38        * page/CaptionUserPreferences.h:
     39
     40        * page/CaptionUserPreferencesMac.h:
     41        * page/CaptionUserPreferencesMac.mm:
     42        (WebCore::CaptionUserPreferencesMac::textTrackSelectionScore): Calculate track language score
     43            according to user preferences.
     44
     45        * platform/Language.cpp:
     46        (WebCore::indexOfBestMatchingLanguageInList): Repurposed the static bestMatchingLanguage
     47            function to return the location of a language in a Vector.
     48        (WebCore::preferredLanguageFromList): Removed.
     49        * platform/Language.h:
     50
    1512013-03-22  ChangSeok Oh  <changseok.oh@collabora.com>
    252
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r146537 r146647  
    30803080}
    30813081
    3082 bool HTMLMediaElement::userIsInterestedInThisTrackKind(String kind) const
    3083 {
    3084     if (m_disableCaptions)
    3085         return false;
     3082void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
     3083{
     3084    ASSERT(group.tracks.size());
    30863085
    30873086    Page* page = document()->page();
    3088     if (!page)
    3089         return false;
    3090 
    3091     CaptionUserPreferences* captionPreferences = page->group().captionPreferences();
    3092     bool userPrefersCaptionsOrSubtitles = m_closedCaptionsVisible || userPrefersCaptions();
    3093 
    3094     if (kind == TextTrack::subtitlesKeyword())
    3095         return captionPreferences->userPrefersSubtitles() || userPrefersCaptionsOrSubtitles;
    3096     if (kind == TextTrack::captionsKeyword())
    3097         return captionPreferences->userPrefersCaptions() || userPrefersCaptionsOrSubtitles;
    3098     if (kind == TextTrack::descriptionsKeyword())
    3099         return captionPreferences->userPrefersTextDescriptions() || userPrefersCaptionsOrSubtitles;
    3100 
    3101     return false;
    3102 }
    3103 
    3104 void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
    3105 {
    3106     ASSERT(group.tracks.size());
    3107 
    3108     String bestMatchingLanguage;
    3109     if (group.hasSrcLang && document()->page()) {
    3110         Vector<String> trackLanguages;
    3111         trackLanguages.reserveInitialCapacity(group.tracks.size());
    3112         for (size_t i = 0; i < group.tracks.size(); ++i) {
    3113             String srcLanguage = group.tracks[i]->language();
    3114             if (srcLanguage.length())
    3115                 trackLanguages.append(srcLanguage);
    3116         }
    3117         bestMatchingLanguage = preferredLanguageFromList(trackLanguages, document()->page()->group().captionPreferences()->preferredLanguages());
    3118     }
     3087    CaptionUserPreferences* captionPreferences = page? page->group().captionPreferences() : 0;
    31193088
    31203089    // First, find the track in the group that should be enabled (if any).
     
    31233092    RefPtr<TextTrack> defaultTrack;
    31243093    RefPtr<TextTrack> fallbackTrack;
     3094    int highestTrackScore = 0;
    31253095    for (size_t i = 0; i < group.tracks.size(); ++i) {
    31263096        RefPtr<TextTrack> textTrack = group.tracks[i];
     
    31293099            currentlyEnabledTracks.append(textTrack);
    31303100
    3131         if (trackToEnable)
    3132             continue;
    3133 
    3134         if (userIsInterestedInThisTrackKind(textTrack->kind())) {
     3101        int trackScore = captionPreferences ? captionPreferences->textTrackSelectionScore(textTrack.get()) : 0;
     3102        if (trackScore) {
    31353103            // * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a
    31363104            // track with this text track kind, text track language, and text track label enabled, and there is no
     
    31423110            // text tracks with a text track kind of chapters whose text track mode is showing
    31433111            //    Let the text track mode be showing.
    3144             if (bestMatchingLanguage.length()) {
    3145                 if (textTrack->language() == bestMatchingLanguage)
    3146                     trackToEnable = textTrack;
    3147             } else if (textTrack->isDefault()) {
    3148                 // The user is interested in this type of track, but their language preference doesn't match any track so we will
    3149                 // enable the 'default' track.
     3112            if (trackScore > highestTrackScore) {
     3113                highestTrackScore = trackScore;
     3114                trackToEnable = textTrack;
     3115            }
     3116
     3117            if (!defaultTrack && textTrack->isDefault())
    31503118                defaultTrack = textTrack;
    3151             }
    3152 
    3153             // Remember the first track that doesn't match language or have 'default' to potentially use as fallback.
    3154             if (!fallbackTrack)
     3119            if (!defaultTrack && !fallbackTrack)
    31553120                fallbackTrack = textTrack;
    31563121        } else if (!group.visibleTrack && !defaultTrack && textTrack->isDefault()) {
     
    43294294#if ENABLE(VIDEO_TRACK)
    43304295    if (RuntimeEnabledFeatures::webkitVideoTrackEnabled()) {
     4296        m_processingPreferenceChange = true;
    43314297        m_disableCaptions = !m_closedCaptionsVisible;
    43324298
     
    45304496        mediaControls()->textTrackPreferencesChanged();
    45314497
    4532     bool prefersCaptions = userPrefersCaptions();
    4533     if (m_disableCaptions == !prefersCaptions)
    4534         return;
    4535 
    4536     m_processingPreferenceChange = true;
    4537     setClosedCaptionsVisible(prefersCaptions);
     4498    setClosedCaptionsVisible(userPrefersCaptions());
    45384499}
    45394500
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r146380 r146647  
    273273
    274274    bool userPrefersCaptions() const;
    275     bool userIsInterestedInThisTrackKind(String) const;
    276275    bool textTracksAreReady() const;
    277276    void configureTextTrackDisplay();
  • trunk/Source/WebCore/html/shadow/MediaControlElements.cpp

    r146380 r146647  
    12551255
    12561256        ASSERT(cue->isActive());
    1257         if (!cue->track() || !cue->track()->isRendered())
     1257        if (!cue->track() || !cue->track()->isRendered() || !cue->isActive())
    12581258            continue;
    12591259
  • trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp

    r144891 r146647  
    307307    MediaControls::changedClosedCaptionsVisibility();
    308308    if (m_closedCaptionsTrackList)
    309         m_closedCaptionsTrackList->updateDisplay();
     309        m_closedCaptionsTrackList->resetTrackListMenu();
    310310}
    311311
  • trunk/Source/WebCore/page/CaptionUserPreferences.cpp

    r146380 r146647  
    5252bool CaptionUserPreferences::shouldShowCaptions() const
    5353{
    54     return m_testingMode ? m_shouldShowCaptions : false;
     54    if (!m_testingMode)
     55        return false;
     56   
     57    return m_shouldShowCaptions || userPrefersCaptions() || userPrefersSubtitles();
    5558}
    5659
     
    7376{
    7477    m_shouldShowCaptions = preference;
     78    if (m_testingMode && !preference) {
     79        setUserPrefersCaptions(false);
     80        setUserPrefersSubtitles(false);
     81    }
    7582    notify();
    7683}
     
    186193}
    187194
     195int CaptionUserPreferences::textTrackSelectionScore(TextTrack* track) const
     196{
     197    int trackScore = 0;
     198
     199    if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword())
     200        return trackScore;
     201
     202    if (track->kind() == TextTrack::subtitlesKeyword() && userPrefersSubtitles())
     203        trackScore = 1;
     204    else if (track->kind() == TextTrack::captionsKeyword() && userPrefersCaptions())
     205        trackScore = 1;
     206   
     207    return trackScore + textTrackLanguageSelectionScore(track);
     208}
     209
     210int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track) const
     211{
     212    if (track->language().isEmpty())
     213        return 0;
     214
     215    Vector<String> languages = preferredLanguages();
     216    size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->language(), languages);
     217    if (languageMatchIndex >= languages.size())
     218        return 0;
     219
     220    // Matching a track language is more important than matching track type, so this multiplier must be
     221    // greater than the maximum value returned by textTrackSelectionScore.
     222    return (languages.size() - languageMatchIndex) * 10;
     223}
     224
    188225}
    189226
  • trunk/Source/WebCore/page/CaptionUserPreferences.h

    r146380 r146647  
    5050    virtual void setShouldShowCaptions(bool);
    5151
     52    virtual int textTrackSelectionScore(TextTrack*) const;
     53    virtual int textTrackLanguageSelectionScore(TextTrack*) const;
     54
    5255    virtual bool userPrefersCaptions() const;
    5356    virtual void setUserPrefersCaptions(bool);
  • trunk/Source/WebCore/page/CaptionUserPreferencesMac.h

    r146380 r146647  
    6161#endif
    6262
     63    virtual int textTrackSelectionScore(TextTrack*) const OVERRIDE;
    6364    virtual Vector<RefPtr<TextTrack> > sortedTrackListForMenu(TextTrackList*) OVERRIDE;
    6465    virtual String displayNameForTrack(TextTrack*) const OVERRIDE;
  • trunk/Source/WebCore/page/CaptionUserPreferencesMac.mm

    r146385 r146647  
    599599}
    600600
     601int CaptionUserPreferencesMac::textTrackSelectionScore(TextTrack* track) const
     602{
     603    if (!shouldShowCaptions())
     604        return 0;
     605    if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword())
     606        return 0;
     607    if (track->containsOnlyForcedSubtitles())
     608        return 0;
     609    if (!track->isMainProgramContent())
     610        return 0;
     611
     612    int trackScore = 0;
     613
     614    if (userPrefersCaptions()) {
     615        // When the user prefers accessiblity tracks, rank is SDH, then CC, then subtitles.
     616        if (track->kind() == track->subtitlesKeyword())
     617            trackScore = 1;
     618        else if (track->isClosedCaptions())
     619            trackScore = 2;
     620        else
     621            trackScore = 3;
     622    } else {
     623        // When the user prefers translation tracks, rank is subtitles, then SDH, then CC tracks.
     624        if (track->kind() == track->subtitlesKeyword())
     625            trackScore = 3;
     626        else if (!track->isClosedCaptions())
     627            trackScore = 2;
     628        else
     629            trackScore = 1;
     630    }
     631
     632    return trackScore + textTrackLanguageSelectionScore(track);
     633}
     634
    601635static bool textTrackCompare(const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b)
    602636{
  • trunk/Source/WebCore/platform/Language.cpp

    r146380 r146647  
    11/*
    2  * Copyright (C) 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    106106}
    107107
    108 static String bestMatchingLanguage(const String& language, const Vector<String>& languageList)
     108size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<String>& languageList)
    109109{
    110     bool canMatchLanguageOnly = (language.length() == 2 || (language.length() >= 3 && language[2] == '-'));
    111110    String languageWithoutLocaleMatch;
    112111    String languageMatchButNotLocale;
     112    size_t languageWithoutLocaleMatchIndex = 0;
     113    size_t languageMatchButNotLocaleMatchIndex = 0;
     114    bool canMatchLanguageOnly = (language.length() == 2 || (language.length() >= 3 && language[2] == '-'));
    113115
    114116    for (size_t i = 0; i < languageList.size(); ++i) {
     
    116118
    117119        if (language == canonicalizedLanguageFromList)
    118             return languageList[i];
     120            return i;
    119121
    120122        if (canMatchLanguageOnly && canonicalizedLanguageFromList.length() >= 2) {
    121123            if (language[0] == canonicalizedLanguageFromList[0] && language[1] == canonicalizedLanguageFromList[1]) {
    122                 if (!languageWithoutLocaleMatch.length() && canonicalizedLanguageFromList.length() == 2)
     124                if (!languageWithoutLocaleMatch.length() && canonicalizedLanguageFromList.length() == 2) {
    123125                    languageWithoutLocaleMatch = languageList[i];
    124                 if (!languageMatchButNotLocale.length() && canonicalizedLanguageFromList.length() >= 3)
     126                    languageWithoutLocaleMatchIndex = i;
     127                }
     128                if (!languageMatchButNotLocale.length() && canonicalizedLanguageFromList.length() >= 3) {
    125129                    languageMatchButNotLocale = languageList[i];
     130                    languageMatchButNotLocaleMatchIndex = i;
     131                }
    126132            }
    127133        }
    128134    }
    129135
    130     // If we have both a language-only match and a languge-but-not-locale match, return the 
     136    // If we have both a language-only match and a languge-but-not-locale match, return the
    131137    // languge-only match as is considered a "better" match. For example, if the list
    132138    // provided has both "en-GB" and "en" and the user prefers "en-US" we will return "en".
    133139    if (languageWithoutLocaleMatch.length())
    134         return languageWithoutLocaleMatch;
     140        return languageWithoutLocaleMatchIndex;
    135141
    136142    if (languageMatchButNotLocale.length())
    137         return languageMatchButNotLocale;
    138    
    139     return emptyString();
    140 }
     143        return languageMatchButNotLocaleMatchIndex;
    141144
    142 String preferredLanguageFromList(const Vector<String>& languageList, const Vector<String> preferredLanguages)
    143 {
    144     for (size_t i = 0; i < preferredLanguages.size(); ++i) {
    145         String bestMatch = bestMatchingLanguage(canonicalLanguageIdentifier(preferredLanguages[i]), languageList);
    146 
    147         if (bestMatch.length())
    148             return bestMatch;
    149     }
    150 
    151     return emptyString();
     145    return languageList.size();
    152146}
    153147
  • trunk/Source/WebCore/platform/Language.h

    r142580 r146647  
    11/*
    2  * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2006, 2010, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3636Vector<String> userPreferredLanguagesOverride();
    3737void overrideUserPreferredLanguages(const Vector<String>&);
    38 String preferredLanguageFromList(const Vector<String>& languageList, const Vector<String> preferredLanguages);
     38size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<String>& languageList);
    3939
    4040// The observer function will be called when system language changes.
Note: See TracChangeset for help on using the changeset viewer.