Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: Source/core/html/track/AutomaticTrackSelection.cpp

Issue 1118613002: Hook up Android closed captions 'enabled' setting to Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressed comments from fs Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/html/track/AutomaticTrackSelection.h" 6 #include "core/html/track/AutomaticTrackSelection.h"
7 7
8 #include "core/html/track/TextTrack.h" 8 #include "core/html/track/TextTrack.h"
9 #include "core/html/track/TextTrackList.h" 9 #include "core/html/track/TextTrackList.h"
10 #include "platform/Language.h" 10 #include "platform/Language.h"
11 11
12 namespace blink { 12 namespace blink {
13 13
14 class TrackGroup { 14 class TrackGroup {
15 STACK_ALLOCATED(); 15 STACK_ALLOCATED();
16 public: 16 public:
17 enum GroupKind { 17 enum GroupKind {
18 CaptionsAndSubtitles, 18 Captions,
19 Subtitles,
19 Description, 20 Description,
20 Chapter, 21 Chapter,
21 Metadata 22 Metadata
22 }; 23 };
23 24
24 explicit TrackGroup(GroupKind kind) 25 explicit TrackGroup(GroupKind kind)
25 : visibleTrack(nullptr) 26 : visibleTrack(nullptr)
26 , defaultTrack(nullptr) 27 , defaultTrack(nullptr)
27 , kind(kind) 28 , kind(kind)
28 , hasSrcLang(false) 29 , hasSrcLang(false)
(...skipping 23 matching lines...) Expand all
52 static int textTrackSelectionScore(const TextTrack& track) 53 static int textTrackSelectionScore(const TextTrack& track)
53 { 54 {
54 if (track.kind() != TextTrack::captionsKeyword() && track.kind() != TextTrac k::subtitlesKeyword()) 55 if (track.kind() != TextTrack::captionsKeyword() && track.kind() != TextTrac k::subtitlesKeyword())
55 return 0; 56 return 0;
56 57
57 return textTrackLanguageSelectionScore(track); 58 return textTrackLanguageSelectionScore(track);
58 } 59 }
59 60
60 AutomaticTrackSelection::AutomaticTrackSelection(const Configuration& configurat ion) 61 AutomaticTrackSelection::AutomaticTrackSelection(const Configuration& configurat ion)
61 : m_configuration(configuration) 62 : m_configuration(configuration)
63 , m_fallbackCaptionOrSubtitleTrack(nullptr)
62 { 64 {
63 } 65 }
64 66
65 void AutomaticTrackSelection::performAutomaticTextTrackSelection(const TrackGrou p& group) 67 PassRefPtrWillBeRawPtr<TextTrack> AutomaticTrackSelection::performAutomaticTextT rackSelection(const TrackGroup& group)
66 { 68 {
67 ASSERT(group.tracks.size()); 69 ASSERT(group.tracks.size());
68 70
69 // First, find the track in the group that should be enabled (if any). 71 // First, find the track in the group that should be enabled (if any).
70 WillBeHeapVector<RefPtrWillBeMember<TextTrack>> currentlyEnabledTracks; 72 WillBeHeapVector<RefPtrWillBeMember<TextTrack>> currentlyEnabledTracks;
71 RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr; 73 RefPtrWillBeRawPtr<TextTrack> preferredTrack = nullptr;
72 RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr; 74 RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr;
73 RefPtrWillBeRawPtr<TextTrack> fallbackTrack = nullptr; 75
74 int highestTrackScore = 0; 76 int highestTrackScore = 0;
77
75 for (size_t i = 0; i < group.tracks.size(); ++i) { 78 for (size_t i = 0; i < group.tracks.size(); ++i) {
76 RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i]; 79 RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i];
77 80
78 if (m_configuration.disableCurrentlyEnabledTracks && textTrack->mode() = = TextTrack::showingKeyword()) 81 if (m_configuration.disableCurrentlyEnabledTracks && textTrack->mode() = = TextTrack::showingKeyword())
79 currentlyEnabledTracks.append(textTrack); 82 currentlyEnabledTracks.append(textTrack);
80 83
81 int trackScore = textTrackSelectionScore(*textTrack); 84 int trackScore = textTrackSelectionScore(*textTrack);
82 if (trackScore) { 85 if (trackScore) {
83 // * If the text track kind is { [subtitles or captions] [descriptio ns] } and the user has indicated an interest in having a 86 // * If the text track kind is subtitles or captions and the user ha s indicated an interest in having a
84 // track with this text track kind, text track language, and text tr ack label enabled, and there is no 87 // track with this text track kind, text track language, and text tr ack label enabled, and there is no
85 // other text track in the media element's list of text tracks with a text track kind of either subtitles 88 // other text track in the media element's list of text tracks with a text track kind of either subtitles
86 // or captions whose text track mode is showing 89 // or captions whose text track mode is showing
87 // ...
88 // * If the text track kind is chapters and the text track language is one that the user agent has reason
89 // to believe is appropriate for the user, and there is no other tex t track in the media element's list of
90 // text tracks with a text track kind of chapters whose text track m ode is showing
91 // Let the text track mode be showing. 90 // Let the text track mode be showing.
91
92 if (trackScore > highestTrackScore) { 92 if (trackScore > highestTrackScore) {
93 preferredTrack = textTrack;
93 highestTrackScore = trackScore; 94 highestTrackScore = trackScore;
94 trackToEnable = textTrack; 95 m_fallbackCaptionOrSubtitleTrack = textTrack;
95 } 96 }
96 97 if (textTrack->isDefault() && !defaultTrack)
97 if (!defaultTrack && textTrack->isDefault())
98 defaultTrack = textTrack; 98 defaultTrack = textTrack;
99 if (!defaultTrack && !fallbackTrack)
100 fallbackTrack = textTrack;
101 } else if (!group.visibleTrack && !defaultTrack && textTrack->isDefault( )) { 99 } else if (!group.visibleTrack && !defaultTrack && textTrack->isDefault( )) {
102 // * If the track element has a default attribute specified, and the re is no other text track in the media 100 // * If the track element has a default attribute specified, and the re is no other text track in the media
103 // element's list of text tracks whose text track mode is showing or showing by default 101 // element's list of text tracks whose text track mode is showing or showing by default
104 // Let the text track mode be showing by default. 102 // Let the text track mode be showing by default.
105 defaultTrack = textTrack; 103 defaultTrack = textTrack;
106 } 104 }
107 } 105 }
108 106
109 if (!trackToEnable && defaultTrack) 107 if (!preferredTrack && defaultTrack)
110 trackToEnable = defaultTrack; 108 preferredTrack = defaultTrack;
111
112 // If no track matches the user's preferred language and non was marked 'def ault', enable the first track
113 // because the user has explicitly stated a preference for this kind of trac k.
114 if (!fallbackTrack && m_configuration.forceEnableSubtitleOrCaptionTrack && g roup.kind == TrackGroup::CaptionsAndSubtitles)
115 fallbackTrack = group.tracks[0];
116
117 if (!trackToEnable && fallbackTrack)
118 trackToEnable = fallbackTrack;
119 109
120 if (currentlyEnabledTracks.size()) { 110 if (currentlyEnabledTracks.size()) {
121 for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) { 111 for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) {
122 RefPtrWillBeRawPtr<TextTrack> textTrack = currentlyEnabledTracks[i]; 112 RefPtrWillBeRawPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
123 if (textTrack != trackToEnable) 113 textTrack->setMode(TextTrack::disabledKeyword());
124 textTrack->setMode(TextTrack::disabledKeyword());
125 } 114 }
126 } 115 }
127 116
128 if (trackToEnable) 117 // Set the default track to showing if group kind is not subtitles or captio ns.
129 trackToEnable->setMode(TextTrack::showingKeyword()); 118 if (defaultTrack && group.kind != TrackGroup::Captions && group.kind != Trac kGroup::Subtitles)
119 defaultTrack->setMode(TextTrack::showingKeyword());
120
121 if (m_configuration.textTrackKindUserPreference == TextTrackKindUserPreferen ce::Default)
122 return defaultTrack;
123
124 return preferredTrack;
130 } 125 }
131 126
132 void AutomaticTrackSelection::enableDefaultMetadataTextTracks(const TrackGroup& group) 127 void AutomaticTrackSelection::enableDefaultMetadataTextTracks(const TrackGroup& group)
133 { 128 {
134 ASSERT(group.tracks.size()); 129 ASSERT(group.tracks.size());
135 130
136 // https://html.spec.whatwg.org/multipage/embedded-content.html#honor-user-p references-for-automatic-text-track-selection 131 // https://html.spec.whatwg.org/multipage/embedded-content.html#honor-user-p references-for-automatic-text-track-selection
137 132
138 // 4. If there are any text tracks in the media element's list of text 133 // 4. If there are any text tracks in the media element's list of text
139 // tracks whose text track kind is metadata that correspond to track 134 // tracks whose text track kind is metadata that correspond to track
140 // elements with a default attribute set whose text track mode is set to 135 // elements with a default attribute set whose text track mode is set to
141 // disabled, then set the text track mode of all such tracks to hidden 136 // disabled, then set the text track mode of all such tracks to hidden
142 for (auto& textTrack : group.tracks) { 137 for (auto& textTrack : group.tracks) {
143 if (textTrack->mode() != TextTrack::disabledKeyword()) 138 if (textTrack->mode() != TextTrack::disabledKeyword())
144 continue; 139 continue;
145 if (!textTrack->isDefault()) 140 if (!textTrack->isDefault())
146 continue; 141 continue;
147 textTrack->setMode(TextTrack::hiddenKeyword()); 142 textTrack->setMode(TextTrack::hiddenKeyword());
148 } 143 }
149 } 144 }
150 145
151 void AutomaticTrackSelection::perform(TextTrackList& textTracks) 146 void AutomaticTrackSelection::perform(TextTrackList& textTracks)
152 { 147 {
153 TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles); 148 TrackGroup captionTracks(TrackGroup::Captions);
philipj_slow 2015/06/24 09:54:20 I see that you have discussed this with fs, but I
fs 2015/06/24 10:23:26 FWIW, this is one of the "further improvements" th
philipj_slow 2015/06/24 10:26:16 That sounds good if it's possible. srivats@, did y
149 TrackGroup subtitleTracks(TrackGroup::Subtitles);
154 TrackGroup descriptionTracks(TrackGroup::Description); 150 TrackGroup descriptionTracks(TrackGroup::Description);
155 TrackGroup chapterTracks(TrackGroup::Chapter); 151 TrackGroup chapterTracks(TrackGroup::Chapter);
156 TrackGroup metadataTracks(TrackGroup::Metadata); 152 TrackGroup metadataTracks(TrackGroup::Metadata);
157 153
158 for (size_t i = 0; i < textTracks.length(); ++i) { 154 for (size_t i = 0; i < textTracks.length(); ++i) {
159 RefPtrWillBeRawPtr<TextTrack> textTrack = textTracks.item(i); 155 RefPtrWillBeRawPtr<TextTrack> textTrack = textTracks.item(i);
160 if (!textTrack) 156 if (!textTrack)
161 continue; 157 continue;
162 158
163 String kind = textTrack->kind(); 159 String kind = textTrack->kind();
164 TrackGroup* currentGroup; 160 TrackGroup* currentGroup;
165 if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captions Keyword()) { 161 if (kind == TextTrack::captionsKeyword()) {
166 currentGroup = &captionAndSubtitleTracks; 162 currentGroup = &captionTracks;
163 } else if (kind == TextTrack::subtitlesKeyword()) {
164 currentGroup = &subtitleTracks;
167 } else if (kind == TextTrack::descriptionsKeyword()) { 165 } else if (kind == TextTrack::descriptionsKeyword()) {
168 currentGroup = &descriptionTracks; 166 currentGroup = &descriptionTracks;
169 } else if (kind == TextTrack::chaptersKeyword()) { 167 } else if (kind == TextTrack::chaptersKeyword()) {
170 currentGroup = &chapterTracks; 168 currentGroup = &chapterTracks;
171 } else { 169 } else {
172 ASSERT(kind == TextTrack::metadataKeyword()); 170 ASSERT(kind == TextTrack::metadataKeyword());
173 currentGroup = &metadataTracks; 171 currentGroup = &metadataTracks;
174 } 172 }
175 173
176 if (!currentGroup->visibleTrack && textTrack->mode() == TextTrack::showi ngKeyword()) 174 if (!currentGroup->visibleTrack && textTrack->mode() == TextTrack::showi ngKeyword())
177 currentGroup->visibleTrack = textTrack; 175 currentGroup->visibleTrack = textTrack;
178 if (!currentGroup->defaultTrack && textTrack->isDefault()) 176 if (!currentGroup->defaultTrack && textTrack->isDefault())
179 currentGroup->defaultTrack = textTrack; 177 currentGroup->defaultTrack = textTrack;
180 178
181 // Do not add this track to the group if it has already been automatical ly configured 179 // Do not add this track to the group if it has already been automatical ly configured
182 // as we only want to perform selection once per track so that adding an other track 180 // as we only want to perform selection once per track so that adding an other track
183 // after the initial configuration doesn't reconfigure every track - onl y those that 181 // after the initial configuration doesn't reconfigure every track - onl y those that
184 // should be changed by the new addition. For example all metadata track s are 182 // should be changed by the new addition. For example all metadata track s are
185 // disabled by default, and we don't want a track that has been enabled by script 183 // disabled by default, and we don't want a track that has been enabled by script
186 // to be disabled automatically when a new metadata track is added later . 184 // to be disabled automatically when a new metadata track is added later .
187 if (textTrack->hasBeenConfigured()) 185 if (textTrack->hasBeenConfigured())
188 continue; 186 continue;
189 187
190 if (textTrack->language().length()) 188 if (textTrack->language().length())
191 currentGroup->hasSrcLang = true; 189 currentGroup->hasSrcLang = true;
192 currentGroup->tracks.append(textTrack); 190 currentGroup->tracks.append(textTrack);
193 } 191 }
194 192
195 if (captionAndSubtitleTracks.tracks.size()) 193 RefPtrWillBeRawPtr<TextTrack> preferredCaptionTrack = nullptr;
196 performAutomaticTextTrackSelection(captionAndSubtitleTracks); 194 if (captionTracks.tracks.size())
195 preferredCaptionTrack = performAutomaticTextTrackSelection(captionTracks );
196
197 RefPtrWillBeRawPtr<TextTrack> preferredSubtitleTrack = nullptr;
198 if (subtitleTracks.tracks.size())
199 preferredSubtitleTrack = performAutomaticTextTrackSelection(subtitleTrac ks);
200
197 if (descriptionTracks.tracks.size()) 201 if (descriptionTracks.tracks.size())
198 performAutomaticTextTrackSelection(descriptionTracks); 202 performAutomaticTextTrackSelection(descriptionTracks);
199 if (chapterTracks.tracks.size()) 203 if (chapterTracks.tracks.size())
200 performAutomaticTextTrackSelection(chapterTracks); 204 performAutomaticTextTrackSelection(chapterTracks);
201 if (metadataTracks.tracks.size()) 205 if (metadataTracks.tracks.size())
202 enableDefaultMetadataTextTracks(metadataTracks); 206 enableDefaultMetadataTextTracks(metadataTracks);
207
208 RefPtrWillBeRawPtr<TextTrack> trackToEnable =
209 enableTrackBasedOnUserPreference(preferredCaptionTrack, preferredSubtitl eTrack);
210 if (m_configuration.forceEnableSubtitleOrCaptionTrack && !trackToEnable) {
211 trackToEnable = m_fallbackCaptionOrSubtitleTrack;
212 if (captionTracks.tracks.size() && !trackToEnable)
213 trackToEnable = captionTracks.tracks[0];
214 else if (subtitleTracks.tracks.size() && !trackToEnable)
215 trackToEnable = subtitleTracks.tracks[0];
216 }
217
218 if (trackToEnable)
219 trackToEnable->setMode(TextTrack::showingKeyword());
220 }
221
222 PassRefPtrWillBeRawPtr<TextTrack> AutomaticTrackSelection::enableTrackBasedOnUse rPreference(
223 PassRefPtrWillBeRawPtr<TextTrack> preferredCaptionTrack, PassRefPtrWillBeRaw Ptr<TextTrack> preferredSubtitleTrack)
224 {
225 RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr;
226 switch (m_configuration.textTrackKindUserPreference) {
227 case TextTrackKindUserPreference::Subtitles:
228 if (preferredSubtitleTrack)
229 trackToEnable = preferredSubtitleTrack;
230 break;
231 case TextTrackKindUserPreference::Default:
232 case TextTrackKindUserPreference::Captions:
233 // When the user prefers captions, display a caption track if present in user's preferred language.
234 // If no captions track exists in the user's preferred language or a sub title track
235 // exists in a language with a higher score, display the subtitle track.
236 int captionTrackScore = 0;
237 int subtitleTrackScore = 0;
238 if (preferredCaptionTrack)
239 captionTrackScore = textTrackSelectionScore(*preferredCaptionTrack);
240 if (preferredSubtitleTrack)
241 subtitleTrackScore = textTrackSelectionScore(*preferredSubtitleTrack );
242 if (captionTrackScore >= subtitleTrackScore && preferredCaptionTrack)
243 trackToEnable = preferredCaptionTrack;
244 else if (preferredSubtitleTrack)
245 trackToEnable = preferredSubtitleTrack;
246 break;
247 }
248 return trackToEnable;
203 } 249 }
204 250
205 } // namespace blink 251 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698