OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/formats/webm/webm_tracks_parser.h" | 5 #include "media/formats/webm/webm_tracks_parser.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 int64 mult = duration_in_ns / 1000; | 37 int64 mult = duration_in_ns / 1000; |
38 mult /= timecode_scale_in_us; | 38 mult /= timecode_scale_in_us; |
39 if (mult == 0) | 39 if (mult == 0) |
40 return kNoTimestamp(); | 40 return kNoTimestamp(); |
41 | 41 |
42 mult = static_cast<double>(mult) * timecode_scale_in_us; | 42 mult = static_cast<double>(mult) * timecode_scale_in_us; |
43 return base::TimeDelta::FromMicroseconds(mult); | 43 return base::TimeDelta::FromMicroseconds(mult); |
44 } | 44 } |
45 | 45 |
46 WebMTracksParser::WebMTracksParser(const LogCB& log_cb, bool ignore_text_tracks) | 46 WebMTracksParser::WebMTracksParser(const scoped_refptr<MediaLog>& media_log, |
| 47 bool ignore_text_tracks) |
47 : track_type_(-1), | 48 : track_type_(-1), |
48 track_num_(-1), | 49 track_num_(-1), |
49 seek_preroll_(-1), | 50 seek_preroll_(-1), |
50 codec_delay_(-1), | 51 codec_delay_(-1), |
51 default_duration_(-1), | 52 default_duration_(-1), |
52 audio_track_num_(-1), | 53 audio_track_num_(-1), |
53 audio_default_duration_(-1), | 54 audio_default_duration_(-1), |
54 video_track_num_(-1), | 55 video_track_num_(-1), |
55 video_default_duration_(-1), | 56 video_default_duration_(-1), |
56 ignore_text_tracks_(ignore_text_tracks), | 57 ignore_text_tracks_(ignore_text_tracks), |
57 log_cb_(log_cb), | 58 media_log_(media_log), |
58 audio_client_(log_cb), | 59 audio_client_(media_log), |
59 video_client_(log_cb) { | 60 video_client_(media_log) { |
60 } | 61 } |
61 | 62 |
62 WebMTracksParser::~WebMTracksParser() {} | 63 WebMTracksParser::~WebMTracksParser() {} |
63 | 64 |
64 int WebMTracksParser::Parse(const uint8* buf, int size) { | 65 int WebMTracksParser::Parse(const uint8* buf, int size) { |
65 track_type_ =-1; | 66 track_type_ =-1; |
66 track_num_ = -1; | 67 track_num_ = -1; |
67 default_duration_ = -1; | 68 default_duration_ = -1; |
68 track_name_.clear(); | 69 track_name_.clear(); |
69 track_language_.clear(); | 70 track_language_.clear(); |
(...skipping 25 matching lines...) Expand all Loading... |
95 base::TimeDelta WebMTracksParser::GetVideoDefaultDuration( | 96 base::TimeDelta WebMTracksParser::GetVideoDefaultDuration( |
96 const double timecode_scale_in_us) const { | 97 const double timecode_scale_in_us) const { |
97 return PrecisionCappedDefaultDuration(timecode_scale_in_us, | 98 return PrecisionCappedDefaultDuration(timecode_scale_in_us, |
98 video_default_duration_); | 99 video_default_duration_); |
99 } | 100 } |
100 | 101 |
101 WebMParserClient* WebMTracksParser::OnListStart(int id) { | 102 WebMParserClient* WebMTracksParser::OnListStart(int id) { |
102 if (id == kWebMIdContentEncodings) { | 103 if (id == kWebMIdContentEncodings) { |
103 DCHECK(!track_content_encodings_client_.get()); | 104 DCHECK(!track_content_encodings_client_.get()); |
104 track_content_encodings_client_.reset( | 105 track_content_encodings_client_.reset( |
105 new WebMContentEncodingsClient(log_cb_)); | 106 new WebMContentEncodingsClient(media_log_)); |
106 return track_content_encodings_client_->OnListStart(id); | 107 return track_content_encodings_client_->OnListStart(id); |
107 } | 108 } |
108 | 109 |
109 if (id == kWebMIdTrackEntry) { | 110 if (id == kWebMIdTrackEntry) { |
110 track_type_ = -1; | 111 track_type_ = -1; |
111 track_num_ = -1; | 112 track_num_ = -1; |
112 default_duration_ = -1; | 113 default_duration_ = -1; |
113 track_name_.clear(); | 114 track_name_.clear(); |
114 track_language_.clear(); | 115 track_language_.clear(); |
115 codec_id_ = ""; | 116 codec_id_ = ""; |
(...skipping 13 matching lines...) Expand all Loading... |
129 } | 130 } |
130 | 131 |
131 bool WebMTracksParser::OnListEnd(int id) { | 132 bool WebMTracksParser::OnListEnd(int id) { |
132 if (id == kWebMIdContentEncodings) { | 133 if (id == kWebMIdContentEncodings) { |
133 DCHECK(track_content_encodings_client_.get()); | 134 DCHECK(track_content_encodings_client_.get()); |
134 return track_content_encodings_client_->OnListEnd(id); | 135 return track_content_encodings_client_->OnListEnd(id); |
135 } | 136 } |
136 | 137 |
137 if (id == kWebMIdTrackEntry) { | 138 if (id == kWebMIdTrackEntry) { |
138 if (track_type_ == -1 || track_num_ == -1) { | 139 if (track_type_ == -1 || track_num_ == -1) { |
139 MEDIA_LOG(ERROR, log_cb_) << "Missing TrackEntry data for " | 140 MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry data for " |
140 << " TrackType " << track_type_ << " TrackNum " | 141 << " TrackType " << track_type_ |
141 << track_num_; | 142 << " TrackNum " << track_num_; |
142 return false; | 143 return false; |
143 } | 144 } |
144 | 145 |
145 if (track_type_ != kWebMTrackTypeAudio && | 146 if (track_type_ != kWebMTrackTypeAudio && |
146 track_type_ != kWebMTrackTypeVideo && | 147 track_type_ != kWebMTrackTypeVideo && |
147 track_type_ != kWebMTrackTypeSubtitlesOrCaptions && | 148 track_type_ != kWebMTrackTypeSubtitlesOrCaptions && |
148 track_type_ != kWebMTrackTypeDescriptionsOrMetadata) { | 149 track_type_ != kWebMTrackTypeDescriptionsOrMetadata) { |
149 MEDIA_LOG(ERROR, log_cb_) << "Unexpected TrackType " << track_type_; | 150 MEDIA_LOG(ERROR, media_log_) << "Unexpected TrackType " << track_type_; |
150 return false; | 151 return false; |
151 } | 152 } |
152 | 153 |
153 TextKind text_track_kind = kTextNone; | 154 TextKind text_track_kind = kTextNone; |
154 if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) { | 155 if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) { |
155 text_track_kind = CodecIdToTextKind(codec_id_); | 156 text_track_kind = CodecIdToTextKind(codec_id_); |
156 if (text_track_kind == kTextNone) { | 157 if (text_track_kind == kTextNone) { |
157 MEDIA_LOG(ERROR, log_cb_) << "Missing TrackEntry CodecID" | 158 MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry CodecID" |
158 << " TrackNum " << track_num_; | 159 << " TrackNum " << track_num_; |
159 return false; | 160 return false; |
160 } | 161 } |
161 | 162 |
162 if (text_track_kind != kTextSubtitles && | 163 if (text_track_kind != kTextSubtitles && |
163 text_track_kind != kTextCaptions) { | 164 text_track_kind != kTextCaptions) { |
164 MEDIA_LOG(ERROR, log_cb_) << "Wrong TrackEntry CodecID" | 165 MEDIA_LOG(ERROR, media_log_) << "Wrong TrackEntry CodecID" |
165 << " TrackNum " << track_num_; | 166 << " TrackNum " << track_num_; |
166 return false; | 167 return false; |
167 } | 168 } |
168 } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { | 169 } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { |
169 text_track_kind = CodecIdToTextKind(codec_id_); | 170 text_track_kind = CodecIdToTextKind(codec_id_); |
170 if (text_track_kind == kTextNone) { | 171 if (text_track_kind == kTextNone) { |
171 MEDIA_LOG(ERROR, log_cb_) << "Missing TrackEntry CodecID" | 172 MEDIA_LOG(ERROR, media_log_) << "Missing TrackEntry CodecID" |
172 << " TrackNum " << track_num_; | 173 << " TrackNum " << track_num_; |
173 return false; | 174 return false; |
174 } | 175 } |
175 | 176 |
176 if (text_track_kind != kTextDescriptions && | 177 if (text_track_kind != kTextDescriptions && |
177 text_track_kind != kTextMetadata) { | 178 text_track_kind != kTextMetadata) { |
178 MEDIA_LOG(ERROR, log_cb_) << "Wrong TrackEntry CodecID" | 179 MEDIA_LOG(ERROR, media_log_) << "Wrong TrackEntry CodecID" |
179 << " TrackNum " << track_num_; | 180 << " TrackNum " << track_num_; |
180 return false; | 181 return false; |
181 } | 182 } |
182 } | 183 } |
183 | 184 |
184 std::string encryption_key_id; | 185 std::string encryption_key_id; |
185 if (track_content_encodings_client_) { | 186 if (track_content_encodings_client_) { |
186 DCHECK(!track_content_encodings_client_->content_encodings().empty()); | 187 DCHECK(!track_content_encodings_client_->content_encodings().empty()); |
187 // If we have multiple ContentEncoding in one track. Always choose the | 188 // If we have multiple ContentEncoding in one track. Always choose the |
188 // key id in the first ContentEncoding as the key id of the track. | 189 // key id in the first ContentEncoding as the key id of the track. |
189 encryption_key_id = track_content_encodings_client_-> | 190 encryption_key_id = track_content_encodings_client_-> |
190 content_encodings()[0]->encryption_key_id(); | 191 content_encodings()[0]->encryption_key_id(); |
191 } | 192 } |
192 | 193 |
193 if (track_type_ == kWebMTrackTypeAudio) { | 194 if (track_type_ == kWebMTrackTypeAudio) { |
194 if (audio_track_num_ == -1) { | 195 if (audio_track_num_ == -1) { |
195 audio_track_num_ = track_num_; | 196 audio_track_num_ = track_num_; |
196 audio_encryption_key_id_ = encryption_key_id; | 197 audio_encryption_key_id_ = encryption_key_id; |
197 | 198 |
198 if (default_duration_ == 0) { | 199 if (default_duration_ == 0) { |
199 MEDIA_LOG(ERROR, log_cb_) << "Illegal 0ns audio TrackEntry " | 200 MEDIA_LOG(ERROR, media_log_) << "Illegal 0ns audio TrackEntry " |
200 "DefaultDuration"; | 201 "DefaultDuration"; |
201 return false; | 202 return false; |
202 } | 203 } |
203 audio_default_duration_ = default_duration_; | 204 audio_default_duration_ = default_duration_; |
204 | 205 |
205 DCHECK(!audio_decoder_config_.IsValidConfig()); | 206 DCHECK(!audio_decoder_config_.IsValidConfig()); |
206 if (!audio_client_.InitializeConfig( | 207 if (!audio_client_.InitializeConfig( |
207 codec_id_, codec_private_, seek_preroll_, codec_delay_, | 208 codec_id_, codec_private_, seek_preroll_, codec_delay_, |
208 !audio_encryption_key_id_.empty(), &audio_decoder_config_)) { | 209 !audio_encryption_key_id_.empty(), &audio_decoder_config_)) { |
209 return false; | 210 return false; |
210 } | 211 } |
211 } else { | 212 } else { |
212 MEDIA_LOG(DEBUG, log_cb_) << "Ignoring audio track " << track_num_; | 213 MEDIA_LOG(DEBUG, media_log_) << "Ignoring audio track " << track_num_; |
213 ignored_tracks_.insert(track_num_); | 214 ignored_tracks_.insert(track_num_); |
214 } | 215 } |
215 } else if (track_type_ == kWebMTrackTypeVideo) { | 216 } else if (track_type_ == kWebMTrackTypeVideo) { |
216 if (video_track_num_ == -1) { | 217 if (video_track_num_ == -1) { |
217 video_track_num_ = track_num_; | 218 video_track_num_ = track_num_; |
218 video_encryption_key_id_ = encryption_key_id; | 219 video_encryption_key_id_ = encryption_key_id; |
219 | 220 |
220 if (default_duration_ == 0) { | 221 if (default_duration_ == 0) { |
221 MEDIA_LOG(ERROR, log_cb_) << "Illegal 0ns video TrackEntry " | 222 MEDIA_LOG(ERROR, media_log_) << "Illegal 0ns video TrackEntry " |
222 "DefaultDuration"; | 223 "DefaultDuration"; |
223 return false; | 224 return false; |
224 } | 225 } |
225 video_default_duration_ = default_duration_; | 226 video_default_duration_ = default_duration_; |
226 | 227 |
227 DCHECK(!video_decoder_config_.IsValidConfig()); | 228 DCHECK(!video_decoder_config_.IsValidConfig()); |
228 if (!video_client_.InitializeConfig( | 229 if (!video_client_.InitializeConfig( |
229 codec_id_, codec_private_, !video_encryption_key_id_.empty(), | 230 codec_id_, codec_private_, !video_encryption_key_id_.empty(), |
230 &video_decoder_config_)) { | 231 &video_decoder_config_)) { |
231 return false; | 232 return false; |
232 } | 233 } |
233 } else { | 234 } else { |
234 MEDIA_LOG(DEBUG, log_cb_) << "Ignoring video track " << track_num_; | 235 MEDIA_LOG(DEBUG, media_log_) << "Ignoring video track " << track_num_; |
235 ignored_tracks_.insert(track_num_); | 236 ignored_tracks_.insert(track_num_); |
236 } | 237 } |
237 } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions || | 238 } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions || |
238 track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { | 239 track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { |
239 if (ignore_text_tracks_) { | 240 if (ignore_text_tracks_) { |
240 MEDIA_LOG(DEBUG, log_cb_) << "Ignoring text track " << track_num_; | 241 MEDIA_LOG(DEBUG, media_log_) << "Ignoring text track " << track_num_; |
241 ignored_tracks_.insert(track_num_); | 242 ignored_tracks_.insert(track_num_); |
242 } else { | 243 } else { |
243 std::string track_num = base::Int64ToString(track_num_); | 244 std::string track_num = base::Int64ToString(track_num_); |
244 text_tracks_[track_num_] = TextTrackConfig( | 245 text_tracks_[track_num_] = TextTrackConfig( |
245 text_track_kind, track_name_, track_language_, track_num); | 246 text_track_kind, track_name_, track_language_, track_num); |
246 } | 247 } |
247 } else { | 248 } else { |
248 MEDIA_LOG(ERROR, log_cb_) << "Unexpected TrackType " << track_type_; | 249 MEDIA_LOG(ERROR, media_log_) << "Unexpected TrackType " << track_type_; |
249 return false; | 250 return false; |
250 } | 251 } |
251 | 252 |
252 track_type_ = -1; | 253 track_type_ = -1; |
253 track_num_ = -1; | 254 track_num_ = -1; |
254 default_duration_ = -1; | 255 default_duration_ = -1; |
255 track_name_.clear(); | 256 track_name_.clear(); |
256 track_language_.clear(); | 257 track_language_.clear(); |
257 codec_id_ = ""; | 258 codec_id_ = ""; |
258 codec_private_.clear(); | 259 codec_private_.clear(); |
(...skipping 24 matching lines...) Expand all Loading... |
283 dst = &codec_delay_; | 284 dst = &codec_delay_; |
284 break; | 285 break; |
285 case kWebMIdDefaultDuration: | 286 case kWebMIdDefaultDuration: |
286 dst = &default_duration_; | 287 dst = &default_duration_; |
287 break; | 288 break; |
288 default: | 289 default: |
289 return true; | 290 return true; |
290 } | 291 } |
291 | 292 |
292 if (*dst != -1) { | 293 if (*dst != -1) { |
293 MEDIA_LOG(ERROR, log_cb_) << "Multiple values for id " << std::hex << id | 294 MEDIA_LOG(ERROR, media_log_) << "Multiple values for id " << std::hex << id |
294 << " specified"; | 295 << " specified"; |
295 return false; | 296 return false; |
296 } | 297 } |
297 | 298 |
298 *dst = val; | 299 *dst = val; |
299 return true; | 300 return true; |
300 } | 301 } |
301 | 302 |
302 bool WebMTracksParser::OnFloat(int id, double val) { | 303 bool WebMTracksParser::OnFloat(int id, double val) { |
303 return true; | 304 return true; |
304 } | 305 } |
305 | 306 |
306 bool WebMTracksParser::OnBinary(int id, const uint8* data, int size) { | 307 bool WebMTracksParser::OnBinary(int id, const uint8* data, int size) { |
307 if (id == kWebMIdCodecPrivate) { | 308 if (id == kWebMIdCodecPrivate) { |
308 if (!codec_private_.empty()) { | 309 if (!codec_private_.empty()) { |
309 MEDIA_LOG(ERROR, log_cb_) << "Multiple CodecPrivate fields in a track."; | 310 MEDIA_LOG(ERROR, media_log_) |
| 311 << "Multiple CodecPrivate fields in a track."; |
310 return false; | 312 return false; |
311 } | 313 } |
312 codec_private_.assign(data, data + size); | 314 codec_private_.assign(data, data + size); |
313 return true; | 315 return true; |
314 } | 316 } |
315 return true; | 317 return true; |
316 } | 318 } |
317 | 319 |
318 bool WebMTracksParser::OnString(int id, const std::string& str) { | 320 bool WebMTracksParser::OnString(int id, const std::string& str) { |
319 if (id == kWebMIdCodecID) { | 321 if (id == kWebMIdCodecID) { |
320 if (!codec_id_.empty()) { | 322 if (!codec_id_.empty()) { |
321 MEDIA_LOG(ERROR, log_cb_) << "Multiple CodecID fields in a track"; | 323 MEDIA_LOG(ERROR, media_log_) << "Multiple CodecID fields in a track"; |
322 return false; | 324 return false; |
323 } | 325 } |
324 | 326 |
325 codec_id_ = str; | 327 codec_id_ = str; |
326 return true; | 328 return true; |
327 } | 329 } |
328 | 330 |
329 if (id == kWebMIdName) { | 331 if (id == kWebMIdName) { |
330 track_name_ = str; | 332 track_name_ = str; |
331 return true; | 333 return true; |
332 } | 334 } |
333 | 335 |
334 if (id == kWebMIdLanguage) { | 336 if (id == kWebMIdLanguage) { |
335 track_language_ = str; | 337 track_language_ = str; |
336 return true; | 338 return true; |
337 } | 339 } |
338 | 340 |
339 return true; | 341 return true; |
340 } | 342 } |
341 | 343 |
342 } // namespace media | 344 } // namespace media |
OLD | NEW |