| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/webm/webm_stream_parser.h" | 5 #include "media/webm/webm_stream_parser.h" | 
| 6 | 6 | 
| 7 #include <string> | 7 #include <string> | 
| 8 | 8 | 
| 9 #include "base/callback.h" | 9 #include "base/callback.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| 11 #include "base/stl_util.h" |  | 
| 12 #include "media/webm/webm_cluster_parser.h" | 11 #include "media/webm/webm_cluster_parser.h" | 
| 13 #include "media/webm/webm_constants.h" | 12 #include "media/webm/webm_constants.h" | 
| 14 #include "media/webm/webm_content_encodings.h" | 13 #include "media/webm/webm_content_encodings.h" | 
| 15 #include "media/webm/webm_crypto_helpers.h" | 14 #include "media/webm/webm_crypto_helpers.h" | 
| 16 #include "media/webm/webm_info_parser.h" | 15 #include "media/webm/webm_info_parser.h" | 
| 17 #include "media/webm/webm_tracks_parser.h" | 16 #include "media/webm/webm_tracks_parser.h" | 
| 18 | 17 | 
| 19 namespace media { | 18 namespace media { | 
| 20 | 19 | 
| 21 WebMStreamParser::WebMStreamParser() | 20 WebMStreamParser::WebMStreamParser() | 
| 22     : state_(kWaitingForInit), | 21     : state_(kWaitingForInit), | 
| 23       waiting_for_buffers_(false) { | 22       waiting_for_buffers_(false) { | 
| 24 } | 23 } | 
| 25 | 24 | 
| 26 WebMStreamParser::~WebMStreamParser() { | 25 WebMStreamParser::~WebMStreamParser() { | 
| 27   STLDeleteValues(&text_track_map_); |  | 
| 28 } | 26 } | 
| 29 | 27 | 
| 30 void WebMStreamParser::Init(const InitCB& init_cb, | 28 void WebMStreamParser::Init(const InitCB& init_cb, | 
| 31                             const NewConfigCB& config_cb, | 29                             const NewConfigCB& config_cb, | 
| 32                             const NewBuffersCB& new_buffers_cb, | 30                             const NewBuffersCB& new_buffers_cb, | 
| 33                             const NewTextBuffersCB& text_cb, | 31                             const NewTextBuffersCB& text_cb, | 
| 34                             const NeedKeyCB& need_key_cb, | 32                             const NeedKeyCB& need_key_cb, | 
| 35                             const AddTextTrackCB& add_text_track_cb, |  | 
| 36                             const NewMediaSegmentCB& new_segment_cb, | 33                             const NewMediaSegmentCB& new_segment_cb, | 
| 37                             const base::Closure& end_of_segment_cb, | 34                             const base::Closure& end_of_segment_cb, | 
| 38                             const LogCB& log_cb) { | 35                             const LogCB& log_cb) { | 
| 39   DCHECK_EQ(state_, kWaitingForInit); | 36   DCHECK_EQ(state_, kWaitingForInit); | 
| 40   DCHECK(init_cb_.is_null()); | 37   DCHECK(init_cb_.is_null()); | 
| 41   DCHECK(!init_cb.is_null()); | 38   DCHECK(!init_cb.is_null()); | 
| 42   DCHECK(!config_cb.is_null()); | 39   DCHECK(!config_cb.is_null()); | 
| 43   DCHECK(!new_buffers_cb.is_null()); | 40   DCHECK(!new_buffers_cb.is_null()); | 
| 44   DCHECK(!text_cb.is_null()); |  | 
| 45   DCHECK(!need_key_cb.is_null()); | 41   DCHECK(!need_key_cb.is_null()); | 
| 46   DCHECK(!new_segment_cb.is_null()); | 42   DCHECK(!new_segment_cb.is_null()); | 
| 47   DCHECK(!end_of_segment_cb.is_null()); | 43   DCHECK(!end_of_segment_cb.is_null()); | 
| 48 | 44 | 
| 49   ChangeState(kParsingHeaders); | 45   ChangeState(kParsingHeaders); | 
| 50   init_cb_ = init_cb; | 46   init_cb_ = init_cb; | 
| 51   config_cb_ = config_cb; | 47   config_cb_ = config_cb; | 
| 52   new_buffers_cb_ = new_buffers_cb; | 48   new_buffers_cb_ = new_buffers_cb; | 
| 53   text_cb_ = text_cb; | 49   text_cb_ = text_cb; | 
| 54   need_key_cb_ = need_key_cb; | 50   need_key_cb_ = need_key_cb; | 
| 55   add_text_track_cb_ = add_text_track_cb; |  | 
| 56   new_segment_cb_ = new_segment_cb; | 51   new_segment_cb_ = new_segment_cb; | 
| 57   end_of_segment_cb_ = end_of_segment_cb; | 52   end_of_segment_cb_ = end_of_segment_cb; | 
| 58   log_cb_ = log_cb; | 53   log_cb_ = log_cb; | 
| 59 } | 54 } | 
| 60 | 55 | 
| 61 void WebMStreamParser::Flush() { | 56 void WebMStreamParser::Flush() { | 
| 62   DCHECK_NE(state_, kWaitingForInit); | 57   DCHECK_NE(state_, kWaitingForInit); | 
| 63 | 58 | 
| 64   byte_queue_.Reset(); | 59   byte_queue_.Reset(); | 
| 65 | 60 | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 168   WebMInfoParser info_parser; | 163   WebMInfoParser info_parser; | 
| 169   result = info_parser.Parse(cur, cur_size); | 164   result = info_parser.Parse(cur, cur_size); | 
| 170 | 165 | 
| 171   if (result <= 0) | 166   if (result <= 0) | 
| 172     return result; | 167     return result; | 
| 173 | 168 | 
| 174   cur += result; | 169   cur += result; | 
| 175   cur_size -= result; | 170   cur_size -= result; | 
| 176   bytes_parsed += result; | 171   bytes_parsed += result; | 
| 177 | 172 | 
| 178   WebMTracksParser tracks_parser(log_cb_, add_text_track_cb_.is_null()); | 173   WebMTracksParser tracks_parser(log_cb_, text_cb_.is_null()); | 
| 179   result = tracks_parser.Parse(cur, cur_size); | 174   result = tracks_parser.Parse(cur, cur_size); | 
| 180 | 175 | 
| 181   if (result <= 0) | 176   if (result <= 0) | 
| 182     return result; | 177     return result; | 
| 183 | 178 | 
| 184   bytes_parsed += result; | 179   bytes_parsed += result; | 
| 185 | 180 | 
| 186   base::TimeDelta duration = kInfiniteDuration(); | 181   base::TimeDelta duration = kInfiniteDuration(); | 
| 187 | 182 | 
| 188   if (info_parser.duration() > 0) { | 183   if (info_parser.duration() > 0) { | 
| 189     double mult = info_parser.timecode_scale() / 1000.0; | 184     double mult = info_parser.timecode_scale() / 1000.0; | 
| 190     int64 duration_in_us = info_parser.duration() * mult; | 185     int64 duration_in_us = info_parser.duration() * mult; | 
| 191     duration = base::TimeDelta::FromMicroseconds(duration_in_us); | 186     duration = base::TimeDelta::FromMicroseconds(duration_in_us); | 
| 192   } | 187   } | 
| 193 | 188 | 
| 194   const AudioDecoderConfig& audio_config = tracks_parser.audio_decoder_config(); | 189   const AudioDecoderConfig& audio_config = tracks_parser.audio_decoder_config(); | 
| 195   if (audio_config.is_encrypted()) | 190   if (audio_config.is_encrypted()) | 
| 196     FireNeedKey(tracks_parser.audio_encryption_key_id()); | 191     FireNeedKey(tracks_parser.audio_encryption_key_id()); | 
| 197 | 192 | 
| 198   const VideoDecoderConfig& video_config = tracks_parser.video_decoder_config(); | 193   const VideoDecoderConfig& video_config = tracks_parser.video_decoder_config(); | 
| 199   if (video_config.is_encrypted()) | 194   if (video_config.is_encrypted()) | 
| 200     FireNeedKey(tracks_parser.video_encryption_key_id()); | 195     FireNeedKey(tracks_parser.video_encryption_key_id()); | 
| 201 | 196 | 
| 202   if (!config_cb_.Run(audio_config, video_config)) { | 197   if (!config_cb_.Run(audio_config, | 
|  | 198                       video_config, | 
|  | 199                       tracks_parser.text_tracks())) { | 
| 203     DVLOG(1) << "New config data isn't allowed."; | 200     DVLOG(1) << "New config data isn't allowed."; | 
| 204     return -1; | 201     return -1; | 
| 205   } | 202   } | 
| 206 | 203 | 
| 207   typedef WebMTracksParser::TextTracks TextTracks; |  | 
| 208   const TextTracks& text_tracks = tracks_parser.text_tracks(); |  | 
| 209 |  | 
| 210   for (TextTracks::const_iterator itr = text_tracks.begin(); |  | 
| 211        itr != text_tracks.end(); ++itr) { |  | 
| 212     const WebMTracksParser::TextTrackInfo& text_track_info = itr->second; |  | 
| 213 |  | 
| 214     // TODO(matthewjheaney): verify that WebVTT uses ISO 639-2 for lang |  | 
| 215     scoped_ptr<TextTrack> text_track = |  | 
| 216         add_text_track_cb_.Run(text_track_info.kind, |  | 
| 217                                text_track_info.name, |  | 
| 218                                text_track_info.language); |  | 
| 219 |  | 
| 220     // Assume ownership of pointer, and cache the text track object, for use |  | 
| 221     // later when we have text track buffers. (The text track objects are |  | 
| 222     // deallocated in the dtor for this class.) |  | 
| 223 |  | 
| 224     if (text_track) |  | 
| 225       text_track_map_.insert(std::make_pair(itr->first, text_track.release())); |  | 
| 226   } |  | 
| 227 |  | 
| 228   cluster_parser_.reset(new WebMClusterParser( | 204   cluster_parser_.reset(new WebMClusterParser( | 
| 229       info_parser.timecode_scale(), | 205       info_parser.timecode_scale(), | 
| 230       tracks_parser.audio_track_num(), | 206       tracks_parser.audio_track_num(), | 
| 231       tracks_parser.video_track_num(), | 207       tracks_parser.video_track_num(), | 
| 232       text_tracks, | 208       tracks_parser.text_tracks(), | 
| 233       tracks_parser.ignored_tracks(), | 209       tracks_parser.ignored_tracks(), | 
| 234       tracks_parser.audio_encryption_key_id(), | 210       tracks_parser.audio_encryption_key_id(), | 
| 235       tracks_parser.video_encryption_key_id(), | 211       tracks_parser.video_encryption_key_id(), | 
| 236       log_cb_)); | 212       log_cb_)); | 
| 237 | 213 | 
| 238   ChangeState(kParsingClusters); | 214   ChangeState(kParsingClusters); | 
| 239 | 215 | 
| 240   if (!init_cb_.is_null()) { | 216   if (!init_cb_.is_null()) { | 
| 241     init_cb_.Run(true, duration); | 217     init_cb_.Run(true, duration); | 
| 242     init_cb_.Reset(); | 218     init_cb_.Reset(); | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 294     return -1; | 270     return -1; | 
| 295   } | 271   } | 
| 296 | 272 | 
| 297   WebMClusterParser::TextTrackIterator text_track_iter = | 273   WebMClusterParser::TextTrackIterator text_track_iter = | 
| 298     cluster_parser_->CreateTextTrackIterator(); | 274     cluster_parser_->CreateTextTrackIterator(); | 
| 299 | 275 | 
| 300   int text_track_num; | 276   int text_track_num; | 
| 301   const BufferQueue* text_buffers; | 277   const BufferQueue* text_buffers; | 
| 302 | 278 | 
| 303   while (text_track_iter(&text_track_num, &text_buffers)) { | 279   while (text_track_iter(&text_track_num, &text_buffers)) { | 
| 304     TextTrackMap::iterator find_result = text_track_map_.find(text_track_num); | 280     if (!text_buffers->empty() && !text_cb_.Run(text_track_num, *text_buffers)) | 
| 305 |  | 
| 306     if (find_result == text_track_map_.end()) |  | 
| 307       continue; |  | 
| 308 |  | 
| 309     TextTrack* const text_track = find_result->second; |  | 
| 310 |  | 
| 311     if (!text_buffers->empty() && !text_cb_.Run(text_track, *text_buffers)) |  | 
| 312       return -1; | 281       return -1; | 
| 313   } | 282   } | 
| 314 | 283 | 
| 315   if (cluster_ended) | 284   if (cluster_ended) | 
| 316     end_of_segment_cb_.Run(); | 285     end_of_segment_cb_.Run(); | 
| 317 | 286 | 
| 318   return bytes_parsed; | 287   return bytes_parsed; | 
| 319 } | 288 } | 
| 320 | 289 | 
| 321 void WebMStreamParser::FireNeedKey(const std::string& key_id) { | 290 void WebMStreamParser::FireNeedKey(const std::string& key_id) { | 
| 322   std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); | 291   std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); | 
| 323   need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); | 292   need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); | 
| 324 } | 293 } | 
| 325 | 294 | 
| 326 }  // namespace media | 295 }  // namespace media | 
| OLD | NEW | 
|---|