diff --git a/packager/media/formats/webvtt/webvtt_parser.cc b/packager/media/formats/webvtt/webvtt_parser.cc index 02d03ef37e..71c9dfcc26 100644 --- a/packager/media/formats/webvtt/webvtt_parser.cc +++ b/packager/media/formats/webvtt/webvtt_parser.cc @@ -59,6 +59,22 @@ bool IsLikelyCueTiming(const std::string& line) { bool MaybeCueId(const std::string& line) { return line.find("-->") == std::string::npos; } + +// Check to see if the block is likely a style block. Style blocks are +// identified as any block that starts with a line that only contains +// "STYLE". +// SOURCE: https://w3c.github.io/webvtt/#styling +bool IsLikelyStyle(const std::string& line) { + return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "STYLE"; +} + +// Check to see if the block is likely a region block. Region blocks are +// identified as any block that starts with a line that only contains +// "REGION". +// SOURCE: https://w3c.github.io/webvtt/#webvtt-region +bool IsLikelyRegion(const std::string& line) { + return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "REGION"; +} } // namespace WebVttParser::WebVttParser(std::unique_ptr source, @@ -113,6 +129,8 @@ bool WebVttParser::Parse() { return false; } + bool saw_cue = false; + while (reader_.Next(&block) && keep_reading_) { // NOTE if (IsLikelyNote(block[0])) { @@ -120,15 +138,41 @@ bool WebVttParser::Parse() { continue; } + // STYLE + if (IsLikelyStyle(block[0])) { + if (saw_cue) { + LOG(ERROR) + << "Found style block after seeing cue. Ignoring style block"; + } else { + LOG(WARNING) << "Missing support for style blocks. Skipping block:\n" + << BlockToString(block.data(), block.size()); + } + continue; + } + + // REGION + if (IsLikelyRegion(block[0])) { + if (saw_cue) { + LOG(ERROR) + << "Found region block after seeing cue. Ignoring region block"; + } else { + LOG(WARNING) << "Missing support for region blocks. Skipping block:\n" + << BlockToString(block.data(), block.size()); + } + continue; + } + // CUE with ID if (block.size() > 2 && MaybeCueId(block[0]) && IsLikelyCueTiming(block[1]) && ParseCueWithId(block)) { + saw_cue = true; continue; } // CUE with no ID if (block.size() > 1 && IsLikelyCueTiming(block[0]) && ParseCueWithNoId(block)) { + saw_cue = true; continue; } diff --git a/packager/media/formats/webvtt/webvtt_parser_unittest.cc b/packager/media/formats/webvtt/webvtt_parser_unittest.cc index 12347ae23a..26a547348e 100644 --- a/packager/media/formats/webvtt/webvtt_parser_unittest.cc +++ b/packager/media/formats/webvtt/webvtt_parser_unittest.cc @@ -123,9 +123,35 @@ TEST_F(WebVttParserTest, FailToParseHeaderNotOneLine) { ASSERT_NE(Status::OK, parser_->Run()); } -// TODO: Add style blocks support to WebVttParser. -// This test is disabled until WebVTT parses STYLE blocks. -TEST_F(WebVttParserTest, DISABLED_ParseStyleBlocks) { +// Right now we don't support region blocks, but for now make sure that we don't +// die if we see a region block. +TEST_F(WebVttParserTest, ParserDoesNotDieOnRegionBlock) { + const char* text = + "WEBVTT\n" + "\n" + "REGION\n" + "id:fred\n" + "width:40%\n" + "lines:3\n" + "regionanchor:0%,100%\n" + "viewportanchor:10%,90%\n" + "scroll:up"; + + ASSERT_NO_FATAL_FAILURE(SetUpAndInitializeGraph(text)); + + { + testing::InSequence s; + EXPECT_CALL(*Output(kOutputIndex), + OnProcess(IsStreamInfo(kStreamIndex, kTimeScale, !kEncrypted))); + EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex)); + } + + ASSERT_OK(parser_->Run()); +} + +// Right now we don't support style blocks, but for now make sure that we don't +// die if we see a style block. +TEST_F(WebVttParserTest, ParserDoesNotDieOnStyleBlock) { const char* text = "WEBVTT\n" "\n"