1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/webm/webm_tracks_parser.h"
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "media/base/buffers.h"
10 #include "media/webm/webm_constants.h"
11 #include "media/webm/webm_content_encodings.h"
15 // Values for TrackType element.
16 static const int kWebMTrackTypeVideo
= 1;
17 static const int kWebMTrackTypeAudio
= 2;
18 static const int kWebMTrackTypeSubtitle
= 0x11;
20 WebMTracksParser::WebMTracksParser(const LogCB
& log_cb
)
28 WebMTracksParser::~WebMTracksParser() {}
30 int WebMTracksParser::Parse(const uint8
* buf
, int size
) {
33 audio_track_num_
= -1;
34 video_track_num_
= -1;
36 WebMListParser
parser(kWebMIdTracks
, this);
37 int result
= parser
.Parse(buf
, size
);
42 // For now we do all or nothing parsing.
43 return parser
.IsParsingComplete() ? result
: 0;
46 WebMParserClient
* WebMTracksParser::OnListStart(int id
) {
47 if (id
== kWebMIdContentEncodings
) {
48 DCHECK(!track_content_encodings_client_
.get());
49 track_content_encodings_client_
.reset(
50 new WebMContentEncodingsClient(log_cb_
));
51 return track_content_encodings_client_
->OnListStart(id
);
54 if (id
== kWebMIdTrackEntry
) {
63 bool WebMTracksParser::OnListEnd(int id
) {
64 if (id
== kWebMIdContentEncodings
) {
65 DCHECK(track_content_encodings_client_
.get());
66 return track_content_encodings_client_
->OnListEnd(id
);
69 if (id
== kWebMIdTrackEntry
) {
70 if (track_type_
== -1 || track_num_
== -1) {
71 MEDIA_LOG(log_cb_
) << "Missing TrackEntry data for "
72 << " TrackType " << track_type_
73 << " TrackNum " << track_num_
;
77 if (track_type_
!= kWebMTrackTypeAudio
&&
78 track_type_
!= kWebMTrackTypeVideo
&&
79 track_type_
!= kWebMTrackTypeSubtitle
) {
80 MEDIA_LOG(log_cb_
) << "Unexpected TrackType " << track_type_
;
84 std::string encryption_key_id
;
85 if (track_content_encodings_client_
.get()) {
86 DCHECK(!track_content_encodings_client_
->content_encodings().empty());
87 // If we have multiple ContentEncoding in one track. Always choose the
88 // key id in the first ContentEncoding as the key id of the track.
89 encryption_key_id
= track_content_encodings_client_
->
90 content_encodings()[0]->encryption_key_id();
93 if (track_type_
== kWebMTrackTypeAudio
) {
94 if (audio_track_num_
== -1) {
95 audio_track_num_
= track_num_
;
96 audio_encryption_key_id_
= encryption_key_id
;
98 MEDIA_LOG(log_cb_
) << "Ignoring audio track " << track_num_
;
99 ignored_tracks_
.insert(track_num_
);
101 } else if (track_type_
== kWebMTrackTypeVideo
) {
102 if (video_track_num_
== -1) {
103 video_track_num_
= track_num_
;
104 video_encryption_key_id_
= encryption_key_id
;
106 MEDIA_LOG(log_cb_
) << "Ignoring video track " << track_num_
;
107 ignored_tracks_
.insert(track_num_
);
109 } else if (track_type_
== kWebMTrackTypeSubtitle
) {
110 MEDIA_LOG(log_cb_
) << "Ignoring subtitle track " << track_num_
;
111 ignored_tracks_
.insert(track_num_
);
113 MEDIA_LOG(log_cb_
) << "Unexpected TrackType " << track_type_
;
119 track_content_encodings_client_
.reset();
126 bool WebMTracksParser::OnUInt(int id
, int64 val
) {
130 case kWebMIdTrackNumber
:
133 case kWebMIdTrackType
:
141 MEDIA_LOG(log_cb_
) << "Multiple values for id " << std::hex
<< id
150 bool WebMTracksParser::OnFloat(int id
, double val
) {
154 bool WebMTracksParser::OnBinary(int id
, const uint8
* data
, int size
) {
158 bool WebMTracksParser::OnString(int id
, const std::string
& str
) {
159 if (id
== kWebMIdCodecID
&& str
!= "A_VORBIS" && str
!= "V_VP8" &&
160 str
.find("D_WEBVTT/") != 0) {
161 MEDIA_LOG(log_cb_
) << "Unexpected CodecID " << str
;