Changeset 147325 in webkit
- Timestamp:
- Apr 1, 2013 8:24:36 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r147322 r147325 1 2013-04-01 Victor Carbune <vcarbune@chromium.org> 2 3 Parsing WebVTT Region Header Metadata 4 https://bugs.webkit.org/show_bug.cgi?id=109818 5 6 Reviewed by Eric Carlson. 7 8 * media/track/captions-webvtt/header-regions.vtt: Added. 9 * media/track/regions-webvtt/text-track-region-parser-expected.txt: Added. 10 * media/track/regions-webvtt/text-track-region-parser.html: Added. 11 1 12 2013-04-01 Andrey Lushnikov <lushnikov@chromium.org> 2 13 -
trunk/Source/WebCore/ChangeLog
r147323 r147325 1 2013-04-01 Victor Carbune <vcarbune@chromium.org> 2 3 Parsing WebVTT Region Header Metadata 4 https://bugs.webkit.org/show_bug.cgi?id=109818 5 6 Reviewed by Eric Carlson. 7 8 This patch enables reading regions from the metadata section of 9 a WebVTT file. The work for defining generic metadata within the 10 WebVTT file header is still work in progress in the TextTrack CG. 11 12 As previous patches, everything is guarded by WEBVTT_REGIONS and 13 is by default disabled in all ports. 14 15 Test: media/track/regions-webvtt/text-track-region-parser.html 16 17 * html/track/LoadableTextTrack.cpp: 18 (WebCore): 19 (WebCore::LoadableTextTrack::newRegionsAvailable): Added method 20 to be called as soon as regions have finished parsing. 21 * html/track/LoadableTextTrack.h: 22 (LoadableTextTrack): 23 * html/track/TextTrack.h: Changed the access modifiers. 24 (TextTrack): 25 * html/track/TextTrackRegion.cpp: 26 (WebCore::TextTrackRegion::setRegionSettings): Entry point for 27 parsing the region settings from a string. 28 (WebCore): 29 (WebCore::TextTrackRegion::getSettingFromString): Maps a string 30 to a RegionSetting value. 31 (WebCore::TextTrackRegion::parseSettingValue): Parses the value 32 of a specific setting. 33 (WebCore::TextTrackRegion::parseSetting): Parses a setting string. 34 * html/track/TextTrackRegion.h: 35 * html/track/WebVTTParser.cpp: 36 (WebCore): 37 (WebCore::WebVTTParser::parseFloatPercentageValue): Helper method 38 to parse a float percentage value (e.g. "50.1%") 39 (WebCore::WebVTTParser::parseFloatPercentageValuePair): Helper method 40 to parse a float percentage value pair (e.g. "50.1%, 30.5%") 41 (WebCore::WebVTTParser::getNewRegions): Retrieves the new regions 42 available for processing. 43 (WebCore::WebVTTParser::parseBytes): 44 (WebCore::WebVTTParser::collectHeader): Generic function to collect 45 header in the metadata region. 46 (WebCore::WebVTTParser::createNewRegion): Creates new region using 47 the existing metadata header name and value. 48 * html/track/WebVTTParser.h: 49 (WebVTTParserClient): 50 (WebVTTParser): 51 * loader/TextTrackLoader.cpp: 52 (WebCore): 53 (WebCore::TextTrackLoader::newRegionsParsed): Called when the 54 regions have been succesfully parsed. 55 (WebCore::TextTrackLoader::getNewRegions): Gets the new regions. 56 * loader/TextTrackLoader.h: 57 (TextTrackLoaderClient): Added methods that need to be implemented. 58 (TextTrackLoader): 59 1 60 2013-04-01 Pavel Feldman <pfeldman@chromium.org> 2 61 -
trunk/Source/WebCore/html/track/LoadableTextTrack.cpp
r136131 r147325 35 35 #include "ScriptExecutionContext.h" 36 36 #include "TextTrackCueList.h" 37 #include "TextTrackRegionList.h" 37 38 38 39 namespace WebCore { … … 124 125 } 125 126 127 #if ENABLE(WEBVTT_REGIONS) 128 void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader) 129 { 130 ASSERT_UNUSED(loader, m_loader == loader); 131 132 Vector<RefPtr<TextTrackRegion> > newRegions; 133 m_loader->getNewRegions(newRegions); 134 135 for (size_t i = 0; i < newRegions.size(); ++i) { 136 newRegions[i]->setTrack(this); 137 regionList()->add(newRegions[i]); 138 } 139 } 140 #endif 141 126 142 size_t LoadableTextTrack::trackElementIndex() 127 143 { -
trunk/Source/WebCore/html/track/LoadableTextTrack.h
r135202 r147325 71 71 virtual void cueLoadingStarted(TextTrackLoader*); 72 72 virtual void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed); 73 #if ENABLE(WEBVTT_REGIONS) 74 virtual void newRegionsAvailable(TextTrackLoader*); 75 #endif 73 76 74 77 LoadableTextTrack(HTMLTrackElement*, const String& kind, const String& label, const String& language); -
trunk/Source/WebCore/html/track/TextTrack.cpp
r146825 r147325 282 282 283 283 #if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS) 284 TextTrackRegionList* TextTrack::regionList() 285 { 286 return ensureTextTrackRegionList(); 287 } 288 284 289 TextTrackRegionList* TextTrack::ensureTextTrackRegionList() 285 290 { -
trunk/Source/WebCore/html/track/TextTrack.h
r146825 r147325 154 154 protected: 155 155 TextTrack(ScriptExecutionContext*, TextTrackClient*, const AtomicString& kind, const AtomicString& label, const AtomicString& language, TextTrackType); 156 #if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS) 157 TextTrackRegionList* regionList(); 158 #endif 156 159 157 160 RefPtr<TextTrackCueList> m_cues; 158 161 159 162 private: 163 160 164 #if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS) 161 165 TextTrackRegionList* ensureTextTrackRegionList(); -
trunk/Source/WebCore/html/track/TextTrackRegion.cpp
r146825 r147325 36 36 37 37 #include "ExceptionCodePlaceholder.h" 38 #include "Logging.h" 39 #include "WebVTTParser.h" 40 #include <wtf/MathExtras.h> 41 #include <wtf/text/StringBuilder.h> 38 42 39 43 namespace WebCore { … … 197 201 void TextTrackRegion::setRegionSettings(const String& input) 198 202 { 199 // FIXME(109818): Parse region header metadata. 203 m_settings = input; 204 unsigned position = 0; 205 206 while (position < input.length()) { 207 while (position < input.length() && WebVTTParser::isValidSettingDelimiter(input[position])) 208 position++; 209 210 if (position >= input.length()) 211 break; 212 213 parseSetting(input, &position); 214 } 215 } 216 217 TextTrackRegion::RegionSetting TextTrackRegion::getSettingFromString(const String& setting) 218 { 219 DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, ("id", AtomicString::ConstructFromLiteral)); 220 DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, ("height", AtomicString::ConstructFromLiteral)); 221 DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, ("width", AtomicString::ConstructFromLiteral)); 222 DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, ("regionanchor", AtomicString::ConstructFromLiteral)); 223 DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, ("viewportanchor", AtomicString::ConstructFromLiteral)); 224 DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, ("scroll", AtomicString::ConstructFromLiteral)); 225 226 if (setting == idKeyword) 227 return Id; 228 if (setting == heightKeyword) 229 return Height; 230 if (setting == widthKeyword) 231 return Width; 232 if (setting == viewportAnchorKeyword) 233 return ViewportAnchor; 234 if (setting == regionAnchorKeyword) 235 return RegionAnchor; 236 if (setting == scrollKeyword) 237 return Scroll; 238 239 return None; 240 } 241 242 void TextTrackRegion::parseSettingValue(RegionSetting setting, const String& value) 243 { 244 DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral)); 245 246 bool isValidSetting; 247 String numberAsString; 248 int number; 249 unsigned position; 250 FloatPoint anchorPosition; 251 252 switch (setting) { 253 case Id: 254 if (value.find("-->") == notFound) 255 m_id = value; 256 break; 257 case Width: 258 number = WebVTTParser::parseFloatPercentageValue(value, isValidSetting); 259 if (isValidSetting) 260 m_width = number; 261 else 262 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Width"); 263 break; 264 case Height: 265 position = 0; 266 267 numberAsString = WebVTTParser::collectDigits(value, &position); 268 number = value.toInt(&isValidSetting); 269 270 if (isValidSetting && number >= 0) 271 m_heightInLines = number; 272 else 273 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Height"); 274 break; 275 case RegionAnchor: 276 anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting); 277 if (isValidSetting) 278 m_regionAnchor = anchorPosition; 279 else 280 LOG(Media, "TextTrackRegion::parseSettingValue, invalid RegionAnchor"); 281 break; 282 case ViewportAnchor: 283 anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting); 284 if (isValidSetting) 285 m_viewportAnchor = anchorPosition; 286 else 287 LOG(Media, "TextTrackRegion::parseSettingValue, invalid ViewportAnchor"); 288 break; 289 case Scroll: 290 if (value == scrollUpValueKeyword) 291 m_scroll = true; 292 else 293 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Scroll"); 294 break; 295 case None: 296 break; 297 } 298 } 299 300 void TextTrackRegion::parseSetting(const String& input, unsigned* position) 301 { 302 String setting = WebVTTParser::collectWord(input, position); 303 304 size_t equalOffset = setting.find('=', 1); 305 if (equalOffset == notFound || !equalOffset || equalOffset == setting.length() - 1) 306 return; 307 308 RegionSetting name = getSettingFromString(setting.substring(0, equalOffset)); 309 String value = setting.substring(equalOffset + 1, setting.length() - 1); 310 311 parseSettingValue(name, value); 200 312 } 201 313 -
trunk/Source/WebCore/html/track/TextTrackRegion.h
r146825 r147325 95 95 }; 96 96 97 RegionSetting getSettingFromString(const String&); 98 99 void parseSettingValue(RegionSetting, const String&); 100 void parseSetting(const String&, unsigned*); 101 97 102 String m_id; 98 103 String m_settings; -
trunk/Source/WebCore/html/track/WebVTTParser.cpp
r145745 r147325 67 67 } 68 68 69 #if ENABLE(WEBVTT_REGIONS) 70 float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValidSetting) 71 { 72 // '%' must be present and at the end of the setting value. 73 if (value.find('%', 1) != value.length() - 1) { 74 isValidSetting = false; 75 return 0; 76 } 77 78 unsigned position = 0; 79 80 StringBuilder floatNumberAsString; 81 floatNumberAsString.append(WebVTTParser::collectDigits(value, &position)); 82 83 if (value[position] == '.') { 84 floatNumberAsString.append("."); 85 position++; 86 87 floatNumberAsString.append(WebVTTParser::collectDigits(value, &position)); 88 } 89 float number = floatNumberAsString.toString().toFloat(&isValidSetting); 90 91 if (isValidSetting && (number <= 0 || number >= 100)) 92 isValidSetting = false; 93 94 return number; 95 } 96 97 FloatPoint WebVTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, bool& isValidSetting) 98 { 99 // The delimiter can't be the first or second value because a pair of 100 // percentages (x%,y%) implies that at least the first two characters 101 // are the first percentage value. 102 size_t delimiterOffset = value.find(delimiter, 2); 103 if (delimiterOffset == notFound || delimiterOffset == value.length() - 1) { 104 isValidSetting = false; 105 return FloatPoint(0, 0); 106 } 107 108 bool isFirstValueValid; 109 float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOffset), isFirstValueValid); 110 111 bool isSecondValueValid; 112 float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), isSecondValueValid); 113 114 isValidSetting = isFirstValueValid && isSecondValueValid; 115 return FloatPoint(firstCoord, secondCoord); 116 } 117 #endif 118 69 119 WebVTTParser::WebVTTParser(WebVTTParserClient* client, ScriptExecutionContext* context) 70 120 : m_scriptExecutionContext(context) … … 83 133 } 84 134 135 #if ENABLE(WEBVTT_REGIONS) 136 void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions) 137 { 138 outputRegions = m_regionList; 139 m_regionList.clear(); 140 } 141 #endif 142 85 143 void WebVTTParser::parseBytes(const char* data, unsigned length) 86 144 { … … 91 149 while (position < length) { 92 150 String line = collectNextLine(data, length, &position); 93 151 94 152 switch (m_state) { 95 153 case Initial: … … 109 167 m_identifierData.clear(); 110 168 break; 111 169 112 170 case Header: 113 171 // 13-18 - Allow a header (comment area) under the WEBVTT line. 172 #if ENABLE(WEBVTT_REGIONS) 173 if (line.isEmpty()) { 174 if (m_client && m_regionList.size()) 175 m_client->newRegionsParsed(); 176 177 m_state = Id; 178 break; 179 } 180 collectHeader(line); 181 182 break; 183 184 case Metadata: 185 #endif 114 186 if (line.isEmpty()) 115 187 m_state = Id; 116 188 break; 117 189 118 190 case Id: 119 191 // 19-29 - Allow any number of line terminators, then initialize new cue values. … … 121 193 break; 122 194 resetCueValues(); 123 195 124 196 // 30-39 - Check if this line contains an optional identifier or timing data. 125 197 m_state = collectCueId(line); 126 198 break; 127 199 128 200 case TimingsAndSettings: 129 201 // 40 - Collect cue timings and settings. 130 202 m_state = collectTimingsAndSettings(line); 131 203 break; 132 204 133 205 case CueText: 134 206 // 41-53 - Collect the cue text, create a cue, and add it to the output. … … 163 235 return true; 164 236 } 237 238 #if ENABLE(WEBVTT_REGIONS) 239 void WebVTTParser::collectHeader(const String& line) 240 { 241 // 4.1 Extension of WebVTT header parsing (11 - 15) 242 DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicString::ConstructFromLiteral)); 243 244 // 15.4 If line contains the character ":" (A U+003A COLON), then set metadata's 245 // name to the substring of line before the first ":" character and 246 // metadata's value to the substring after this character. 247 if (!line.contains(":")) 248 return; 249 250 unsigned colonPosition = line.find(":"); 251 m_currentHeaderName = line.substring(0, colonPosition); 252 253 // 15.5 If metadata's name equals "Region": 254 if (m_currentHeaderName == regionHeaderName) { 255 m_currentHeaderValue = line.substring(colonPosition + 1, line.length() - 1); 256 // 15.5.1 - 15.5.8 Region creation: Let region be a new text track region [...] 257 createNewRegion(); 258 } 259 } 260 #endif 165 261 166 262 WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line) … … 282 378 m_currentContent.clear(); 283 379 } 380 381 #if ENABLE(WEBVTT_REGIONS) 382 void WebVTTParser::createNewRegion() 383 { 384 if (!m_currentHeaderValue.length()) 385 return; 386 387 RefPtr<TextTrackRegion> region = TextTrackRegion::create(); 388 region->setRegionSettings(m_currentHeaderValue); 389 390 // 15.5.10 If the text track list of regions regions contains a region 391 // with the same region identifier value as region, remove that region. 392 for (size_t i = 0; i < m_regionList.size(); ++i) 393 if (m_regionList[i]->id() == region->id()) { 394 m_regionList.remove(i); 395 break; 396 } 397 398 m_regionList.append(region); 399 } 400 #endif 284 401 285 402 double WebVTTParser::collectTimeStamp(const String& line, unsigned* position) -
trunk/Source/WebCore/html/track/WebVTTParser.h
r140877 r147325 37 37 #include "HTMLNames.h" 38 38 #include "TextTrackCue.h" 39 #include "TextTrackRegion.h" 39 40 #include "WebVTTTokenizer.h" 40 41 #include <wtf/PassOwnPtr.h> … … 50 51 public: 51 52 virtual ~WebVTTParserClient() { } 52 53 53 54 virtual void newCuesParsed() = 0; 55 #if ENABLE(WEBVTT_REGIONS) 56 virtual void newRegionsParsed() = 0; 57 #endif 54 58 virtual void fileFailedToParse() = 0; 55 59 }; … … 58 62 public: 59 63 virtual ~WebVTTParser() { } 60 61 enum ParseState { Initial, Header, Id, TimingsAndSettings, CueText, BadCue }; 64 65 enum ParseState { 66 Initial, 67 Header, 68 #if ENABLE(WEBVTT_REGIONS) 69 Metadata, 70 #endif 71 Id, 72 TimingsAndSettings, 73 CueText, 74 BadCue 75 }; 62 76 63 77 static PassOwnPtr<WebVTTParser> create(WebVTTParserClient* client, ScriptExecutionContext* context) … … 89 103 static String collectWord(const String&, unsigned*); 90 104 105 #if ENABLE(WEBVTT_REGIONS) 106 // Useful functions for parsing percentage settings. 107 static float parseFloatPercentageValue(const String&, bool&); 108 static FloatPoint parseFloatPercentageValuePair(const String&, char, bool&); 109 #endif 110 91 111 // Input data to the parser to parse. 92 112 void parseBytes(const char* data, unsigned length); … … 94 114 // Transfers ownership of last parsed cues to caller. 95 115 void getNewCues(Vector<RefPtr<TextTrackCue> >&); 116 #if ENABLE(WEBVTT_REGIONS) 117 void getNewRegions(Vector<RefPtr<TextTrackRegion> >&); 118 #endif 96 119 97 120 PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(const String&); … … 100 123 protected: 101 124 WebVTTParser(WebVTTParserClient*, ScriptExecutionContext*); 102 125 103 126 ScriptExecutionContext* m_scriptExecutionContext; 104 127 ParseState m_state; … … 114 137 void resetCueValues(); 115 138 139 #if ENABLE(WEBVTT_REGIONS) 140 void collectHeader(const String&); 141 void createNewRegion(); 142 #endif 143 116 144 void skipWhiteSpace(const String&, unsigned*); 117 145 static void skipLineTerminator(const char* data, unsigned length, unsigned*); 118 146 static String collectNextLine(const char* data, unsigned length, unsigned*); 119 147 120 148 void constructTreeFromToken(Document*); 149 150 String m_currentHeaderName; 151 String m_currentHeaderValue; 121 152 122 153 Vector<char> m_identifierData; … … 136 167 Vector<AtomicString> m_languageStack; 137 168 Vector<RefPtr<TextTrackCue> > m_cuelist; 169 170 #if ENABLE(WEBVTT_REGIONS) 171 Vector<RefPtr<TextTrackRegion> > m_regionList; 172 #endif 138 173 }; 139 174 -
trunk/Source/WebCore/loader/TextTrackLoader.cpp
r145745 r147325 189 189 } 190 190 191 #if ENABLE(WEBVTT_REGIONS) 192 void TextTrackLoader::newRegionsParsed() 193 { 194 m_client->newRegionsAvailable(this); 195 } 196 #endif 197 191 198 void TextTrackLoader::fileFailedToParse() 192 199 { … … 208 215 } 209 216 210 } 211 217 #if ENABLE(WEBVTT_REGIONS) 218 void TextTrackLoader::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions) 219 { 220 ASSERT(m_cueParser); 221 if (m_cueParser) 222 m_cueParser->getNewRegions(outputRegions); 223 } 212 224 #endif 225 } 226 227 #endif -
trunk/Source/WebCore/loader/TextTrackLoader.h
r144565 r147325 50 50 virtual void cueLoadingStarted(TextTrackLoader*) = 0; 51 51 virtual void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed) = 0; 52 #if ENABLE(WEBVTT_REGIONS) 53 virtual void newRegionsAvailable(TextTrackLoader*) = 0; 54 #endif 52 55 }; 53 56 … … 65 68 void cancelLoad(); 66 69 void getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues); 67 70 #if ENABLE(WEBVTT_REGIONS) 71 void getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions); 72 #endif 68 73 private: 69 74 … … 74 79 // WebVTTParserClient 75 80 virtual void newCuesParsed(); 81 #if ENABLE(WEBVTT_REGIONS) 82 virtual void newRegionsParsed(); 83 #endif 76 84 virtual void fileFailedToParse(); 77 85
Note: See TracChangeset
for help on using the changeset viewer.