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 11 matching lines...) Expand all Loading... |
22 | 22 |
23 if (codec_id == kWebMCodecDescriptions) | 23 if (codec_id == kWebMCodecDescriptions) |
24 return kTextDescriptions; | 24 return kTextDescriptions; |
25 | 25 |
26 if (codec_id == kWebMCodecMetadata) | 26 if (codec_id == kWebMCodecMetadata) |
27 return kTextMetadata; | 27 return kTextMetadata; |
28 | 28 |
29 return kTextNone; | 29 return kTextNone; |
30 } | 30 } |
31 | 31 |
| 32 static base::TimeDelta PrecisionCappedDefaultDuration( |
| 33 const double timecode_scale_in_us, const int64 duration_in_ns) { |
| 34 if (duration_in_ns <= 0) |
| 35 return kNoTimestamp(); |
| 36 |
| 37 int64 mult = duration_in_ns / 1000; |
| 38 mult /= timecode_scale_in_us; |
| 39 if (mult == 0) |
| 40 return kNoTimestamp(); |
| 41 |
| 42 mult = static_cast<double>(mult) * timecode_scale_in_us; |
| 43 return base::TimeDelta::FromMicroseconds(mult); |
| 44 } |
| 45 |
32 WebMTracksParser::WebMTracksParser(const LogCB& log_cb, bool ignore_text_tracks) | 46 WebMTracksParser::WebMTracksParser(const LogCB& log_cb, bool ignore_text_tracks) |
33 : track_type_(-1), | 47 : track_type_(-1), |
34 track_num_(-1), | 48 track_num_(-1), |
35 track_uid_(-1), | 49 track_uid_(-1), |
36 seek_preroll_(-1), | 50 seek_preroll_(-1), |
37 codec_delay_(-1), | 51 codec_delay_(-1), |
| 52 default_duration_(-1), |
38 audio_track_num_(-1), | 53 audio_track_num_(-1), |
| 54 audio_default_duration_(-1), |
39 video_track_num_(-1), | 55 video_track_num_(-1), |
| 56 video_default_duration_(-1), |
40 ignore_text_tracks_(ignore_text_tracks), | 57 ignore_text_tracks_(ignore_text_tracks), |
41 log_cb_(log_cb), | 58 log_cb_(log_cb), |
42 audio_client_(log_cb), | 59 audio_client_(log_cb), |
43 video_client_(log_cb) { | 60 video_client_(log_cb) { |
44 } | 61 } |
45 | 62 |
46 WebMTracksParser::~WebMTracksParser() {} | 63 WebMTracksParser::~WebMTracksParser() {} |
47 | 64 |
48 int WebMTracksParser::Parse(const uint8* buf, int size) { | 65 int WebMTracksParser::Parse(const uint8* buf, int size) { |
49 track_type_ =-1; | 66 track_type_ =-1; |
50 track_num_ = -1; | 67 track_num_ = -1; |
51 track_uid_ = -1; | 68 track_uid_ = -1; |
| 69 default_duration_ = -1; |
52 track_name_.clear(); | 70 track_name_.clear(); |
53 track_language_.clear(); | 71 track_language_.clear(); |
54 audio_track_num_ = -1; | 72 audio_track_num_ = -1; |
| 73 audio_default_duration_ = -1; |
55 audio_decoder_config_ = AudioDecoderConfig(); | 74 audio_decoder_config_ = AudioDecoderConfig(); |
56 video_track_num_ = -1; | 75 video_track_num_ = -1; |
| 76 video_default_duration_ = -1; |
57 video_decoder_config_ = VideoDecoderConfig(); | 77 video_decoder_config_ = VideoDecoderConfig(); |
58 text_tracks_.clear(); | 78 text_tracks_.clear(); |
59 ignored_tracks_.clear(); | 79 ignored_tracks_.clear(); |
60 | 80 |
61 WebMListParser parser(kWebMIdTracks, this); | 81 WebMListParser parser(kWebMIdTracks, this); |
62 int result = parser.Parse(buf, size); | 82 int result = parser.Parse(buf, size); |
63 | 83 |
64 if (result <= 0) | 84 if (result <= 0) |
65 return result; | 85 return result; |
66 | 86 |
67 // For now we do all or nothing parsing. | 87 // For now we do all or nothing parsing. |
68 return parser.IsParsingComplete() ? result : 0; | 88 return parser.IsParsingComplete() ? result : 0; |
69 } | 89 } |
70 | 90 |
| 91 base::TimeDelta WebMTracksParser::GetAudioDefaultDuration( |
| 92 const double timecode_scale_in_us) const { |
| 93 return PrecisionCappedDefaultDuration(timecode_scale_in_us, |
| 94 audio_default_duration_); |
| 95 } |
| 96 |
| 97 base::TimeDelta WebMTracksParser::GetVideoDefaultDuration( |
| 98 const double timecode_scale_in_us) const { |
| 99 return PrecisionCappedDefaultDuration(timecode_scale_in_us, |
| 100 video_default_duration_); |
| 101 } |
| 102 |
71 WebMParserClient* WebMTracksParser::OnListStart(int id) { | 103 WebMParserClient* WebMTracksParser::OnListStart(int id) { |
72 if (id == kWebMIdContentEncodings) { | 104 if (id == kWebMIdContentEncodings) { |
73 DCHECK(!track_content_encodings_client_.get()); | 105 DCHECK(!track_content_encodings_client_.get()); |
74 track_content_encodings_client_.reset( | 106 track_content_encodings_client_.reset( |
75 new WebMContentEncodingsClient(log_cb_)); | 107 new WebMContentEncodingsClient(log_cb_)); |
76 return track_content_encodings_client_->OnListStart(id); | 108 return track_content_encodings_client_->OnListStart(id); |
77 } | 109 } |
78 | 110 |
79 if (id == kWebMIdTrackEntry) { | 111 if (id == kWebMIdTrackEntry) { |
80 track_type_ = -1; | 112 track_type_ = -1; |
81 track_num_ = -1; | 113 track_num_ = -1; |
| 114 default_duration_ = -1; |
82 track_name_.clear(); | 115 track_name_.clear(); |
83 track_language_.clear(); | 116 track_language_.clear(); |
84 codec_id_ = ""; | 117 codec_id_ = ""; |
85 codec_private_.clear(); | 118 codec_private_.clear(); |
86 audio_client_.Reset(); | 119 audio_client_.Reset(); |
87 video_client_.Reset(); | 120 video_client_.Reset(); |
88 return this; | 121 return this; |
89 } | 122 } |
90 | 123 |
91 if (id == kWebMIdAudio) | 124 if (id == kWebMIdAudio) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 // key id in the first ContentEncoding as the key id of the track. | 191 // key id in the first ContentEncoding as the key id of the track. |
159 encryption_key_id = track_content_encodings_client_-> | 192 encryption_key_id = track_content_encodings_client_-> |
160 content_encodings()[0]->encryption_key_id(); | 193 content_encodings()[0]->encryption_key_id(); |
161 } | 194 } |
162 | 195 |
163 if (track_type_ == kWebMTrackTypeAudio) { | 196 if (track_type_ == kWebMTrackTypeAudio) { |
164 if (audio_track_num_ == -1) { | 197 if (audio_track_num_ == -1) { |
165 audio_track_num_ = track_num_; | 198 audio_track_num_ = track_num_; |
166 audio_encryption_key_id_ = encryption_key_id; | 199 audio_encryption_key_id_ = encryption_key_id; |
167 | 200 |
| 201 if (default_duration_ == 0) { |
| 202 MEDIA_LOG(log_cb_) << "Illegal 0ns audio TrackEntry DefaultDuration"; |
| 203 return false; |
| 204 } |
| 205 audio_default_duration_ = default_duration_; |
| 206 |
168 DCHECK(!audio_decoder_config_.IsValidConfig()); | 207 DCHECK(!audio_decoder_config_.IsValidConfig()); |
169 if (!audio_client_.InitializeConfig( | 208 if (!audio_client_.InitializeConfig( |
170 codec_id_, codec_private_, seek_preroll_, codec_delay_, | 209 codec_id_, codec_private_, seek_preroll_, codec_delay_, |
171 !audio_encryption_key_id_.empty(), &audio_decoder_config_)) { | 210 !audio_encryption_key_id_.empty(), &audio_decoder_config_)) { |
172 return false; | 211 return false; |
173 } | 212 } |
174 } else { | 213 } else { |
175 MEDIA_LOG(log_cb_) << "Ignoring audio track " << track_num_; | 214 MEDIA_LOG(log_cb_) << "Ignoring audio track " << track_num_; |
176 ignored_tracks_.insert(track_num_); | 215 ignored_tracks_.insert(track_num_); |
177 } | 216 } |
178 } else if (track_type_ == kWebMTrackTypeVideo) { | 217 } else if (track_type_ == kWebMTrackTypeVideo) { |
179 if (video_track_num_ == -1) { | 218 if (video_track_num_ == -1) { |
180 video_track_num_ = track_num_; | 219 video_track_num_ = track_num_; |
181 video_encryption_key_id_ = encryption_key_id; | 220 video_encryption_key_id_ = encryption_key_id; |
182 | 221 |
| 222 if (default_duration_ == 0) { |
| 223 MEDIA_LOG(log_cb_) << "Illegal 0ns video TrackEntry DefaultDuration"; |
| 224 return false; |
| 225 } |
| 226 video_default_duration_ = default_duration_; |
| 227 |
183 DCHECK(!video_decoder_config_.IsValidConfig()); | 228 DCHECK(!video_decoder_config_.IsValidConfig()); |
184 if (!video_client_.InitializeConfig( | 229 if (!video_client_.InitializeConfig( |
185 codec_id_, codec_private_, !video_encryption_key_id_.empty(), | 230 codec_id_, codec_private_, !video_encryption_key_id_.empty(), |
186 &video_decoder_config_)) { | 231 &video_decoder_config_)) { |
187 return false; | 232 return false; |
188 } | 233 } |
189 } else { | 234 } else { |
190 MEDIA_LOG(log_cb_) << "Ignoring video track " << track_num_; | 235 MEDIA_LOG(log_cb_) << "Ignoring video track " << track_num_; |
191 ignored_tracks_.insert(track_num_); | 236 ignored_tracks_.insert(track_num_); |
192 } | 237 } |
(...skipping 10 matching lines...) Expand all Loading... |
203 track_uid); | 248 track_uid); |
204 } | 249 } |
205 } else { | 250 } else { |
206 MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_; | 251 MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_; |
207 return false; | 252 return false; |
208 } | 253 } |
209 | 254 |
210 track_type_ = -1; | 255 track_type_ = -1; |
211 track_num_ = -1; | 256 track_num_ = -1; |
212 track_uid_ = -1; | 257 track_uid_ = -1; |
| 258 default_duration_ = -1; |
213 track_name_.clear(); | 259 track_name_.clear(); |
214 track_language_.clear(); | 260 track_language_.clear(); |
215 codec_id_ = ""; | 261 codec_id_ = ""; |
216 codec_private_.clear(); | 262 codec_private_.clear(); |
217 track_content_encodings_client_.reset(); | 263 track_content_encodings_client_.reset(); |
218 | 264 |
219 audio_client_.Reset(); | 265 audio_client_.Reset(); |
220 video_client_.Reset(); | 266 video_client_.Reset(); |
221 return true; | 267 return true; |
222 } | 268 } |
(...skipping 13 matching lines...) Expand all Loading... |
236 break; | 282 break; |
237 case kWebMIdTrackUID: | 283 case kWebMIdTrackUID: |
238 dst = &track_uid_; | 284 dst = &track_uid_; |
239 break; | 285 break; |
240 case kWebMIdSeekPreRoll: | 286 case kWebMIdSeekPreRoll: |
241 dst = &seek_preroll_; | 287 dst = &seek_preroll_; |
242 break; | 288 break; |
243 case kWebMIdCodecDelay: | 289 case kWebMIdCodecDelay: |
244 dst = &codec_delay_; | 290 dst = &codec_delay_; |
245 break; | 291 break; |
| 292 case kWebMIdDefaultDuration: |
| 293 dst = &default_duration_; |
| 294 break; |
246 default: | 295 default: |
247 return true; | 296 return true; |
248 } | 297 } |
249 | 298 |
250 if (*dst != -1) { | 299 if (*dst != -1) { |
251 MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id | 300 MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id |
252 << " specified"; | 301 << " specified"; |
253 return false; | 302 return false; |
254 } | 303 } |
255 | 304 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 341 |
293 if (id == kWebMIdLanguage) { | 342 if (id == kWebMIdLanguage) { |
294 track_language_ = str; | 343 track_language_ = str; |
295 return true; | 344 return true; |
296 } | 345 } |
297 | 346 |
298 return true; | 347 return true; |
299 } | 348 } |
300 | 349 |
301 } // namespace media | 350 } // namespace media |
OLD | NEW |