summaryrefslogtreecommitdiffstats
path: root/media/webm
diff options
context:
space:
mode:
authormatthewjheaney@chromium.org <matthewjheaney@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-08 02:20:25 +0000
committermatthewjheaney@chromium.org <matthewjheaney@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-08 02:20:25 +0000
commit4d5a0faa1170057dbbb6caabca181cd648adea24 (patch)
tree86c723d9321fee8fb92910d6fa6b4c7ad550cd79 /media/webm
parent8c711adfd9e9d958c078488526d901963478d1aa (diff)
downloadchromium_src-4d5a0faa1170057dbbb6caabca181cd648adea24.zip
chromium_src-4d5a0faa1170057dbbb6caabca181cd648adea24.tar.gz
chromium_src-4d5a0faa1170057dbbb6caabca181cd648adea24.tar.bz2
media source should ignore subtitles in webm files
BUG=167152 Review URL: https://chromiumcodereview.appspot.com/11635058 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181410 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/webm')
-rw-r--r--media/webm/webm_cluster_parser.cc69
-rw-r--r--media/webm/webm_cluster_parser.h34
-rw-r--r--media/webm/webm_cluster_parser_unittest.cc165
-rw-r--r--media/webm/webm_parser.h9
-rw-r--r--media/webm/webm_stream_parser.cc5
-rw-r--r--media/webm/webm_tracks_parser.cc75
-rw-r--r--media/webm/webm_tracks_parser.h6
7 files changed, 350 insertions, 13 deletions
diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc
index 785a89d..8a984c8 100644
--- a/media/webm/webm_cluster_parser.cc
+++ b/media/webm/webm_cluster_parser.cc
@@ -23,8 +23,41 @@ static std::string GenerateCounterBlock(const uint8* iv, int iv_size) {
return counter_block;
}
+WebMClusterParser::TextTrackIterator::TextTrackIterator(
+ const TextTrackMap& text_track_map) :
+ iterator_(text_track_map.begin()),
+ iterator_end_(text_track_map.end()) {
+}
+
+WebMClusterParser::TextTrackIterator::TextTrackIterator(
+ const TextTrackIterator& rhs) :
+ iterator_(rhs.iterator_),
+ iterator_end_(rhs.iterator_end_) {
+}
+
+WebMClusterParser::TextTrackIterator::~TextTrackIterator() {
+}
+
+bool WebMClusterParser::TextTrackIterator::operator()(
+ int* track_num,
+ const BufferQueue** buffers) {
+ if (iterator_ == iterator_end_) {
+ *track_num = 0;
+ *buffers = NULL;
+
+ return false;
+ }
+
+ *track_num = iterator_->first;
+ *buffers = &iterator_->second.buffers();
+
+ ++iterator_;
+ return true;
+}
+
WebMClusterParser::WebMClusterParser(
int64 timecode_scale, int audio_track_num, int video_track_num,
+ const std::set<int>& text_tracks,
const std::set<int64>& ignored_tracks,
const std::string& audio_encryption_key_id,
const std::string& video_encryption_key_id,
@@ -43,6 +76,11 @@ WebMClusterParser::WebMClusterParser(
audio_(audio_track_num, false),
video_(video_track_num, true),
log_cb_(log_cb) {
+ for (std::set<int>::const_iterator it = text_tracks.begin();
+ it != text_tracks.end();
+ ++it) {
+ text_track_map_.insert(std::make_pair(*it, Track(*it, false)));
+ }
}
WebMClusterParser::~WebMClusterParser() {}
@@ -55,11 +93,13 @@ void WebMClusterParser::Reset() {
parser_.Reset();
audio_.Reset();
video_.Reset();
+ ResetTextTracks();
}
int WebMClusterParser::Parse(const uint8* buf, int size) {
audio_.Reset();
video_.Reset();
+ ResetTextTracks();
int result = parser_.Parse(buf, size);
@@ -90,6 +130,11 @@ int WebMClusterParser::Parse(const uint8* buf, int size) {
return result;
}
+WebMClusterParser::TextTrackIterator
+WebMClusterParser::CreateTextTrackIterator() const {
+ return TextTrackIterator(text_track_map_);
+}
+
WebMParserClient* WebMClusterParser::OnListStart(int id) {
if (id == kWebMIdCluster) {
cluster_timecode_ = -1;
@@ -219,6 +264,12 @@ bool WebMClusterParser::OnBlock(bool is_simple_block, int track_num,
encryption_key_id = video_encryption_key_id_;
} else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) {
return true;
+ } else if (Track* const text_track = FindTextTrack(track_num)) {
+ if (is_simple_block) // BlockGroup is required for WebVTT cues
+ return false;
+ if (block_duration < 0) // not specified
+ return false;
+ track = text_track;
} else {
MEDIA_LOG(log_cb_) << "Unexpected track number " << track_num;
return false;
@@ -336,4 +387,22 @@ bool WebMClusterParser::Track::IsKeyframe(const uint8* data, int size) const {
return true;
}
+void WebMClusterParser::ResetTextTracks() {
+ for (TextTrackMap::iterator it = text_track_map_.begin();
+ it != text_track_map_.end();
+ ++it) {
+ it->second.Reset();
+ }
+}
+
+WebMClusterParser::Track*
+WebMClusterParser::FindTextTrack(int track_num) {
+ const TextTrackMap::iterator it = text_track_map_.find(track_num);
+
+ if (it == text_track_map_.end())
+ return NULL;
+
+ return &it->second;
+}
+
} // namespace media
diff --git a/media/webm/webm_cluster_parser.h b/media/webm/webm_cluster_parser.h
index 29e4490..a1a5175 100644
--- a/media/webm/webm_cluster_parser.h
+++ b/media/webm/webm_cluster_parser.h
@@ -6,6 +6,7 @@
#define MEDIA_WEBM_WEBM_CLUSTER_PARSER_H_
#include <deque>
+#include <map>
#include <set>
#include <string>
@@ -18,12 +19,33 @@
namespace media {
class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
+ class Track;
+ typedef std::map<int, Track> TextTrackMap;
public:
typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
+ class MEDIA_EXPORT TextTrackIterator {
+ public:
+ explicit TextTrackIterator(const TextTrackMap& text_track_map);
+ TextTrackIterator(const TextTrackIterator& rhs);
+ ~TextTrackIterator();
+
+ // To visit each text track. If the iterator is exhausted, it returns
+ // as parameters the values 0 and NULL, and the function returns false.
+ // Otherwise, it returns the buffers for the associated track, and the
+ // function returns true.
+ bool operator()(int* track_num, const BufferQueue** buffers);
+ private:
+ TextTrackIterator& operator=(const TextTrackIterator&);
+
+ TextTrackMap::const_iterator iterator_;
+ const TextTrackMap::const_iterator iterator_end_;
+ };
+
WebMClusterParser(int64 timecode_scale,
int audio_track_num,
int video_track_num,
+ const std::set<int>& text_tracks,
const std::set<int64>& ignored_tracks,
const std::string& audio_encryption_key_id,
const std::string& video_encryption_key_id,
@@ -44,6 +66,9 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
const BufferQueue& audio_buffers() const { return audio_.buffers(); }
const BufferQueue& video_buffers() const { return video_.buffers(); }
+ // Returns an iterator object, allowing each text track to be visited.
+ TextTrackIterator CreateTextTrackIterator() const;
+
// Returns true if the last Parse() call stopped at the end of a cluster.
bool cluster_ended() const { return cluster_ended_; }
@@ -85,6 +110,13 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
bool OnBlock(bool is_simple_block, int track_num, int timecode, int duration,
int flags, const uint8* data, int size);
+ // Resets the Track objects associated with each text track.
+ void ResetTextTracks();
+
+ // Search for the indicated track_num among the text tracks. Returns NULL
+ // if that track num is not a text track.
+ Track* FindTextTrack(int track_num);
+
double timecode_multiplier_; // Multiplier used to convert timecodes into
// microseconds.
std::set<int64> ignored_tracks_;
@@ -104,7 +136,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
Track audio_;
Track video_;
-
+ TextTrackMap text_track_map_;
LogCB log_cb_;
DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser);
diff --git a/media/webm/webm_cluster_parser_unittest.cc b/media/webm/webm_cluster_parser_unittest.cc
index 034c072..07deb05 100644
--- a/media/webm/webm_cluster_parser_unittest.cc
+++ b/media/webm/webm_cluster_parser_unittest.cc
@@ -69,10 +69,12 @@ static scoped_ptr<Cluster> CreateCluster(int timecode,
static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers,
const WebMClusterParser::BufferQueue& video_buffers,
+ const WebMClusterParser::BufferQueue& text_buffers,
const BlockInfo* block_info,
int block_count) {
size_t audio_offset = 0;
size_t video_offset = 0;
+ size_t text_offset = 0;
for (int i = 0; i < block_count; i++) {
const WebMClusterParser::BufferQueue* buffers = NULL;
size_t* offset;
@@ -83,6 +85,9 @@ static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers,
} else if (block_info[i].track_num == kVideoTrackNum) {
buffers = &video_buffers;
offset = &video_offset;
+ } else if (block_info[i].track_num == kTextTrackNum) {
+ buffers = &text_buffers;
+ offset = &text_offset;
} else {
LOG(ERROR) << "Unexpected track number " << block_info[i].track_num;
return false;
@@ -109,12 +114,57 @@ static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers,
static bool VerifyBuffers(const scoped_ptr<WebMClusterParser>& parser,
const BlockInfo* block_info,
int block_count) {
+ typedef WebMClusterParser::TextTrackIterator TextTrackIterator;
+ TextTrackIterator text_it = parser->CreateTextTrackIterator();
+
+ int text_track_num;
+ const WebMClusterParser::BufferQueue* text_buffers;
+
+ while (text_it(&text_track_num, &text_buffers))
+ break;
+
+ const WebMClusterParser::BufferQueue no_text_buffers;
+
+ if (text_buffers == NULL)
+ text_buffers = &no_text_buffers;
+
return VerifyBuffers(parser->audio_buffers(),
parser->video_buffers(),
+ *text_buffers,
block_info,
block_count);
}
+static bool VerifyTextBuffers(
+ const scoped_ptr<WebMClusterParser>& parser,
+ const BlockInfo* block_info_ptr,
+ int block_count,
+ int text_track_num,
+ const WebMClusterParser::BufferQueue& text_buffers) {
+ const BlockInfo* const block_info_end = block_info_ptr + block_count;
+
+ typedef WebMClusterParser::BufferQueue::const_iterator TextBufferIter;
+ TextBufferIter buffer_iter = text_buffers.begin();
+ const TextBufferIter buffer_end = text_buffers.end();
+
+ while (block_info_ptr != block_info_end) {
+ const BlockInfo& block_info = *block_info_ptr++;
+
+ if (block_info.track_num != text_track_num)
+ continue;
+
+ EXPECT_FALSE(block_info.use_simple_block);
+ EXPECT_FALSE(buffer_iter == buffer_end);
+
+ const scoped_refptr<StreamParserBuffer> buffer = *buffer_iter++;
+ EXPECT_EQ(buffer->GetTimestamp().InMilliseconds(), block_info.timestamp);
+ EXPECT_EQ(buffer->GetDuration().InMilliseconds(), block_info.duration);
+ }
+
+ EXPECT_TRUE(buffer_iter == buffer_end);
+ return true;
+}
+
static void AppendToEnd(const WebMClusterParser::BufferQueue& src,
WebMClusterParser::BufferQueue* dest) {
for (WebMClusterParser::BufferQueue::const_iterator itr = src.begin();
@@ -127,8 +177,11 @@ class WebMClusterParserTest : public testing::Test {
public:
WebMClusterParserTest()
: parser_(new WebMClusterParser(
- kTimecodeScale, kAudioTrackNum, kVideoTrackNum, std::set<int64>(),
- "", "", LogCB())) {
+ kTimecodeScale, kAudioTrackNum, kVideoTrackNum,
+ std::set<int>(),
+ std::set<int64>(),
+ "", "",
+ LogCB())) {
}
protected:
@@ -171,6 +224,7 @@ TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) {
WebMClusterParser::BufferQueue audio_buffers;
WebMClusterParser::BufferQueue video_buffers;
+ const WebMClusterParser::BufferQueue no_text_buffers;
const uint8* data = cluster->data();
int size = cluster->size();
@@ -197,7 +251,8 @@ TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) {
data += result;
size -= result;
}
- ASSERT_TRUE(VerifyBuffers(audio_buffers, video_buffers, kDefaultBlockInfo,
+ ASSERT_TRUE(VerifyBuffers(audio_buffers, video_buffers,
+ no_text_buffers, kDefaultBlockInfo,
block_count));
}
@@ -253,7 +308,9 @@ TEST_F(WebMClusterParserTest, IgnoredTracks) {
ignored_tracks.insert(kTextTrackNum);
parser_.reset(new WebMClusterParser(
- kTimecodeScale, kAudioTrackNum, kVideoTrackNum, ignored_tracks, "", "",
+ kTimecodeScale, kAudioTrackNum, kVideoTrackNum,
+ std::set<int>(),
+ ignored_tracks, "", "",
LogCB()));
const BlockInfo kInputBlockInfo[] = {
@@ -283,4 +340,104 @@ TEST_F(WebMClusterParserTest, IgnoredTracks) {
ASSERT_TRUE(VerifyBuffers(parser_, kOutputBlockInfo, output_block_count));
}
+TEST_F(WebMClusterParserTest, ParseTextTracks) {
+ std::set<int> text_tracks;
+ text_tracks.insert(kTextTrackNum);
+
+ parser_.reset(new WebMClusterParser(
+ kTimecodeScale, kAudioTrackNum, kVideoTrackNum,
+ text_tracks,
+ std::set<int64>(), "", "",
+ LogCB()));
+
+ const BlockInfo kInputBlockInfo[] = {
+ { kAudioTrackNum, 0, 23, true },
+ { kAudioTrackNum, 23, 23, true },
+ { kVideoTrackNum, 33, 33, true },
+ { kTextTrackNum, 33, 42, false },
+ { kAudioTrackNum, 46, 23, true },
+ { kTextTrackNum, 55, 44, false },
+ { kVideoTrackNum, 67, 33, true },
+ };
+ int input_block_count = arraysize(kInputBlockInfo);
+
+ scoped_ptr<Cluster> cluster(
+ CreateCluster(0, kInputBlockInfo, input_block_count));
+
+ int result = parser_->Parse(cluster->data(), cluster->size());
+ EXPECT_EQ(cluster->size(), result);
+ ASSERT_TRUE(VerifyBuffers(parser_, kInputBlockInfo, input_block_count));
+}
+
+TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) {
+ std::set<int> text_tracks;
+ text_tracks.insert(kTextTrackNum);
+
+ parser_.reset(new WebMClusterParser(
+ kTimecodeScale, kAudioTrackNum, kVideoTrackNum,
+ text_tracks,
+ std::set<int64>(), "", "",
+ LogCB()));
+
+ const BlockInfo kInputBlockInfo[] = {
+ { kTextTrackNum, 33, 42, true },
+ };
+ int input_block_count = arraysize(kInputBlockInfo);
+
+ scoped_ptr<Cluster> cluster(
+ CreateCluster(0, kInputBlockInfo, input_block_count));
+
+ int result = parser_->Parse(cluster->data(), cluster->size());
+ EXPECT_LT(result, 0);
+}
+
+TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) {
+ typedef std::set<int> TextTrackSet;
+ TextTrackSet text_tracks;
+
+ const int kSubtitleTextTrackNum = kTextTrackNum;
+ const int kCaptionTextTrackNum = kTextTrackNum + 1;
+
+ text_tracks.insert(kSubtitleTextTrackNum);
+ text_tracks.insert(kCaptionTextTrackNum);
+
+ parser_.reset(new WebMClusterParser(
+ kTimecodeScale, kAudioTrackNum, kVideoTrackNum,
+ text_tracks,
+ std::set<int64>(), "", "",
+ LogCB()));
+
+ const BlockInfo kInputBlockInfo[] = {
+ { kAudioTrackNum, 0, 23, true },
+ { kAudioTrackNum, 23, 23, true },
+ { kVideoTrackNum, 33, 33, true },
+ { kSubtitleTextTrackNum, 33, 42, false },
+ { kAudioTrackNum, 46, 23, true },
+ { kCaptionTextTrackNum, 55, 44, false },
+ { kVideoTrackNum, 67, 33, true },
+ { kSubtitleTextTrackNum, 67, 33, false },
+ };
+ int input_block_count = arraysize(kInputBlockInfo);
+
+ scoped_ptr<Cluster> cluster(
+ CreateCluster(0, kInputBlockInfo, input_block_count));
+
+ int result = parser_->Parse(cluster->data(), cluster->size());
+ EXPECT_EQ(cluster->size(), result);
+
+ WebMClusterParser::TextTrackIterator text_it =
+ parser_->CreateTextTrackIterator();
+
+ int text_track_num;
+ const WebMClusterParser::BufferQueue* text_buffers;
+
+ while (text_it(&text_track_num, &text_buffers)) {
+ const TextTrackSet::const_iterator find_result =
+ text_tracks.find(text_track_num);
+ ASSERT_TRUE(find_result != text_tracks.end());
+ ASSERT_TRUE(VerifyTextBuffers(parser_, kInputBlockInfo, input_block_count,
+ text_track_num, *text_buffers));
+ }
+}
+
} // namespace media
diff --git a/media/webm/webm_parser.h b/media/webm/webm_parser.h
index 68611a8..1fa71e7 100644
--- a/media/webm/webm_parser.h
+++ b/media/webm/webm_parser.h
@@ -153,6 +153,15 @@ class MEDIA_EXPORT WebMListParser {
int MEDIA_EXPORT WebMParseElementHeader(const uint8* buf, int size,
int* id, int64* element_size);
+// Specifies the varieties of text tracks.
+enum TextKind {
+ kTextNone,
+ kTextSubtitles,
+ kTextCaptions,
+ kTextDescriptions,
+ kTextMetadata
+};
+
} // namespace media
#endif // MEDIA_WEBM_WEBM_PARSER_H_
diff --git a/media/webm/webm_stream_parser.cc b/media/webm/webm_stream_parser.cc
index 02c1357..db854a9 100644
--- a/media/webm/webm_stream_parser.cc
+++ b/media/webm/webm_stream_parser.cc
@@ -294,6 +294,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) {
case kWebMIdVoid:
case kWebMIdCRC32:
case kWebMIdCues:
+ case kWebMIdChapters:
if (cur_size < (result + element_size)) {
// We don't have the whole element yet. Signal we need more data.
return 0;
@@ -395,6 +396,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) {
info_parser.timecode_scale(),
tracks_parser.audio_track_num(),
tracks_parser.video_track_num(),
+ tracks_parser.text_tracks(),
tracks_parser.ignored_tracks(),
tracks_parser.audio_encryption_key_id(),
tracks_parser.video_encryption_key_id(),
@@ -424,7 +426,8 @@ int WebMStreamParser::ParseCluster(const uint8* data, int size) {
if (id == kWebMIdCluster)
waiting_for_buffers_ = true;
- if (id == kWebMIdCues) {
+ // TODO(matthewjheaney): implement support for chapters
+ if (id == kWebMIdCues || id == kWebMIdChapters) {
if (size < (result + element_size)) {
// We don't have the whole element yet. Signal we need more data.
return 0;
diff --git a/media/webm/webm_tracks_parser.cc b/media/webm/webm_tracks_parser.cc
index 508530b..2dbac41 100644
--- a/media/webm/webm_tracks_parser.cc
+++ b/media/webm/webm_tracks_parser.cc
@@ -15,11 +15,13 @@ namespace media {
// Values for TrackType element.
static const int kWebMTrackTypeVideo = 1;
static const int kWebMTrackTypeAudio = 2;
-static const int kWebMTrackTypeSubtitle = 0x11;
+static const int kWebMTrackTypeSubtitlesOrCaptions = 0x11;
+static const int kWebMTrackTypeDescriptionsOrMetadata = 0x21;
WebMTracksParser::WebMTracksParser(const LogCB& log_cb)
: track_type_(-1),
track_num_(-1),
+ text_track_kind_(kTextNone),
audio_track_num_(-1),
video_track_num_(-1),
log_cb_(log_cb) {
@@ -30,8 +32,11 @@ WebMTracksParser::~WebMTracksParser() {}
int WebMTracksParser::Parse(const uint8* buf, int size) {
track_type_ =-1;
track_num_ = -1;
+ text_track_kind_ = kTextNone;
audio_track_num_ = -1;
video_track_num_ = -1;
+ text_tracks_.clear();
+ ignored_tracks_.clear();
WebMListParser parser(kWebMIdTracks, this);
int result = parser.Parse(buf, size);
@@ -54,6 +59,7 @@ WebMParserClient* WebMTracksParser::OnListStart(int id) {
if (id == kWebMIdTrackEntry) {
track_type_ = -1;
track_num_ = -1;
+ text_track_kind_ = kTextNone;
return this;
}
@@ -76,11 +82,40 @@ bool WebMTracksParser::OnListEnd(int id) {
if (track_type_ != kWebMTrackTypeAudio &&
track_type_ != kWebMTrackTypeVideo &&
- track_type_ != kWebMTrackTypeSubtitle) {
+ track_type_ != kWebMTrackTypeSubtitlesOrCaptions &&
+ track_type_ != kWebMTrackTypeDescriptionsOrMetadata) {
MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_;
return false;
}
+ if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) {
+ if (text_track_kind_ == kTextNone) {
+ MEDIA_LOG(log_cb_) << "Missing TrackEntry CodecID"
+ << " TrackNum " << track_num_;
+ return false;
+ }
+
+ if (text_track_kind_ != kTextSubtitles &&
+ text_track_kind_ != kTextCaptions) {
+ MEDIA_LOG(log_cb_) << "Wrong TrackEntry CodecID"
+ << " TrackNum " << track_num_;
+ return false;
+ }
+ } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
+ if (text_track_kind_ == kTextNone) {
+ MEDIA_LOG(log_cb_) << "Missing TrackEntry CodecID"
+ << " TrackNum " << track_num_;
+ return false;
+ }
+
+ if (text_track_kind_ != kTextDescriptions &&
+ text_track_kind_ != kTextMetadata) {
+ MEDIA_LOG(log_cb_) << "Wrong TrackEntry CodecID"
+ << " TrackNum " << track_num_;
+ return false;
+ }
+ }
+
std::string encryption_key_id;
if (track_content_encodings_client_.get()) {
DCHECK(!track_content_encodings_client_->content_encodings().empty());
@@ -106,9 +141,9 @@ bool WebMTracksParser::OnListEnd(int id) {
MEDIA_LOG(log_cb_) << "Ignoring video track " << track_num_;
ignored_tracks_.insert(track_num_);
}
- } else if (track_type_ == kWebMTrackTypeSubtitle) {
- MEDIA_LOG(log_cb_) << "Ignoring subtitle track " << track_num_;
- ignored_tracks_.insert(track_num_);
+ } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions ||
+ track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
+ text_tracks_.insert(track_num_);
} else {
MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_;
return false;
@@ -117,6 +152,7 @@ bool WebMTracksParser::OnListEnd(int id) {
track_type_ = -1;
track_num_ = -1;
track_content_encodings_client_.reset();
+ text_track_kind_ = kTextNone;
return true;
}
@@ -156,8 +192,33 @@ bool WebMTracksParser::OnBinary(int id, const uint8* data, int size) {
}
bool WebMTracksParser::OnString(int id, const std::string& str) {
- if (id == kWebMIdCodecID && str != "A_VORBIS" && str != "V_VP8" &&
- str.find("D_WEBVTT/") != 0) {
+ if (id == kWebMIdCodecID) {
+ if (str == "V_VP8")
+ return true;
+
+ if (str == "A_VORBIS")
+ return true;
+
+ if (str == "D_WEBVTT/SUBTITLES") {
+ text_track_kind_ = kTextSubtitles;
+ return true;
+ }
+
+ if (str == "D_WEBVTT/CAPTIONS") {
+ text_track_kind_ = kTextCaptions;
+ return true;
+ }
+
+ if (str == "D_WEBVTT/DESCRIPTIONS") {
+ text_track_kind_ = kTextDescriptions;
+ return true;
+ }
+
+ if (str == "D_WEBVTT/METADATA") {
+ text_track_kind_ = kTextMetadata;
+ return true;
+ }
+
MEDIA_LOG(log_cb_) << "Unexpected CodecID " << str;
return false;
}
diff --git a/media/webm/webm_tracks_parser.h b/media/webm/webm_tracks_parser.h
index 8af3678..5593349 100644
--- a/media/webm/webm_tracks_parser.h
+++ b/media/webm/webm_tracks_parser.h
@@ -40,6 +40,10 @@ class WebMTracksParser : public WebMParserClient {
return video_encryption_key_id_;
}
+ const std::set<int>& text_tracks() const {
+ return text_tracks_;
+ }
+
private:
// WebMParserClient methods
virtual WebMParserClient* OnListStart(int id) OVERRIDE;
@@ -52,9 +56,11 @@ class WebMTracksParser : public WebMParserClient {
int64 track_type_;
int64 track_num_;
scoped_ptr<WebMContentEncodingsClient> track_content_encodings_client_;
+ TextKind text_track_kind_;
int64 audio_track_num_;
int64 video_track_num_;
+ std::set<int> text_tracks_;
std::set<int64> ignored_tracks_;
std::string audio_encryption_key_id_;
std::string video_encryption_key_id_;