| 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 |