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