| 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 "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "media/ffmpeg/ffmpeg_common.h" | 9 #include "media/ffmpeg/ffmpeg_common.h" |
| 10 #include "media/filters/ffmpeg_glue.h" | 10 #include "media/filters/ffmpeg_glue.h" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 AVStreamToVideoDecoderConfig(stream, &video_config_); | 174 AVStreamToVideoDecoderConfig(stream, &video_config_); |
| 175 no_supported_streams = false; | 175 no_supported_streams = false; |
| 176 continue; | 176 continue; |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 | 179 |
| 180 return !no_supported_streams; | 180 return !no_supported_streams; |
| 181 } | 181 } |
| 182 | 182 |
| 183 WebMStreamParser::WebMStreamParser() | 183 WebMStreamParser::WebMStreamParser() |
| 184 : state_(WAITING_FOR_INIT), | 184 : state_(kWaitingForInit), |
| 185 host_(NULL) { | 185 host_(NULL) { |
| 186 } | 186 } |
| 187 | 187 |
| 188 WebMStreamParser::~WebMStreamParser() {} | 188 WebMStreamParser::~WebMStreamParser() {} |
| 189 | 189 |
| 190 void WebMStreamParser::Init(const InitCB& init_cb, StreamParserHost* host) { | 190 void WebMStreamParser::Init(const InitCB& init_cb, StreamParserHost* host) { |
| 191 DCHECK_EQ(state_, WAITING_FOR_INIT); | 191 DCHECK_EQ(state_, kWaitingForInit); |
| 192 DCHECK(init_cb_.is_null()); | 192 DCHECK(init_cb_.is_null()); |
| 193 DCHECK(!host_); | 193 DCHECK(!host_); |
| 194 DCHECK(!init_cb.is_null()); | 194 DCHECK(!init_cb.is_null()); |
| 195 DCHECK(host); | 195 DCHECK(host); |
| 196 | 196 |
| 197 ChangeState(PARSING_HEADERS); | 197 ChangeState(kParsingHeaders); |
| 198 init_cb_ = init_cb; | 198 init_cb_ = init_cb; |
| 199 host_ = host; | 199 host_ = host; |
| 200 } | 200 } |
| 201 | 201 |
| 202 void WebMStreamParser::Flush() { | 202 void WebMStreamParser::Flush() { |
| 203 DCHECK_NE(state_, WAITING_FOR_INIT); | 203 DCHECK_NE(state_, kWaitingForInit); |
| 204 | 204 |
| 205 if (state_ != PARSING_CLUSTERS) | 205 byte_queue_.Reset(); |
| 206 |
| 207 if (state_ != kParsingClusters) |
| 206 return; | 208 return; |
| 207 | 209 |
| 208 cluster_parser_->Reset(); | 210 cluster_parser_->Reset(); |
| 209 } | 211 } |
| 210 | 212 |
| 211 int WebMStreamParser::Parse(const uint8* buf, int size) { | 213 bool WebMStreamParser::Parse(const uint8* buf, int size) { |
| 212 DCHECK_NE(state_, WAITING_FOR_INIT); | 214 DCHECK_NE(state_, kWaitingForInit); |
| 213 | 215 |
| 214 if (state_ == PARSING_HEADERS) | 216 if (state_ == kError) |
| 215 return ParseInfoAndTracks(buf, size); | 217 return false; |
| 216 | 218 |
| 217 if (state_ == PARSING_CLUSTERS) | 219 byte_queue_.Push(buf, size); |
| 218 return ParseCluster(buf, size); | |
| 219 | 220 |
| 220 return -1; | 221 int result = 0; |
| 222 int bytes_parsed = 0; |
| 223 const uint8* cur = NULL; |
| 224 int cur_size = 0; |
| 225 |
| 226 byte_queue_.Peek(&cur, &cur_size); |
| 227 do { |
| 228 switch (state_) { |
| 229 case kParsingHeaders: |
| 230 result = ParseInfoAndTracks(cur, cur_size); |
| 231 break; |
| 232 |
| 233 case kParsingClusters: |
| 234 result = ParseCluster(cur, cur_size); |
| 235 break; |
| 236 |
| 237 case kWaitingForInit: |
| 238 case kError: |
| 239 return false; |
| 240 } |
| 241 |
| 242 if (result < 0) { |
| 243 ChangeState(kError); |
| 244 return false; |
| 245 } |
| 246 |
| 247 cur += result; |
| 248 cur_size -= result; |
| 249 bytes_parsed += result; |
| 250 } while (result > 0 && cur_size > 0); |
| 251 |
| 252 byte_queue_.Pop(bytes_parsed); |
| 253 return true; |
| 221 } | 254 } |
| 222 | 255 |
| 223 void WebMStreamParser::ChangeState(State new_state) { | 256 void WebMStreamParser::ChangeState(State new_state) { |
| 224 state_ = new_state; | 257 state_ = new_state; |
| 225 } | 258 } |
| 226 | 259 |
| 227 int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { | 260 int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { |
| 228 DCHECK(data); | 261 DCHECK(data); |
| 229 DCHECK_GT(size, 0); | 262 DCHECK_GT(size, 0); |
| 230 | 263 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 double mult = info_parser.timecode_scale() / 1000.0; | 321 double mult = info_parser.timecode_scale() / 1000.0; |
| 289 int64 duration_in_us = info_parser.duration() * mult; | 322 int64 duration_in_us = info_parser.duration() * mult; |
| 290 duration = base::TimeDelta::FromMicroseconds(duration_in_us); | 323 duration = base::TimeDelta::FromMicroseconds(duration_in_us); |
| 291 } | 324 } |
| 292 | 325 |
| 293 FFmpegConfigHelper config_helper; | 326 FFmpegConfigHelper config_helper; |
| 294 | 327 |
| 295 if (!config_helper.Parse(data, bytes_parsed)) | 328 if (!config_helper.Parse(data, bytes_parsed)) |
| 296 return -1; | 329 return -1; |
| 297 | 330 |
| 298 if (config_helper.audio_config().IsValidConfig()) | 331 host_->OnNewConfigs(config_helper.audio_config(), |
| 299 host_->OnNewAudioConfig(config_helper.audio_config()); | 332 config_helper.video_config()); |
| 300 | |
| 301 if (config_helper.video_config().IsValidConfig()) | |
| 302 host_->OnNewVideoConfig(config_helper.video_config()); | |
| 303 | 333 |
| 304 cluster_parser_.reset(new WebMClusterParser( | 334 cluster_parser_.reset(new WebMClusterParser( |
| 305 info_parser.timecode_scale(), | 335 info_parser.timecode_scale(), |
| 306 tracks_parser.audio_track_num(), | 336 tracks_parser.audio_track_num(), |
| 307 tracks_parser.audio_default_duration(), | 337 tracks_parser.audio_default_duration(), |
| 308 tracks_parser.video_track_num(), | 338 tracks_parser.video_track_num(), |
| 309 tracks_parser.video_default_duration(), | 339 tracks_parser.video_default_duration(), |
| 310 tracks_parser.video_encryption_key_id(), | 340 tracks_parser.video_encryption_key_id(), |
| 311 tracks_parser.video_encryption_key_id_size())); | 341 tracks_parser.video_encryption_key_id_size())); |
| 312 | 342 |
| 313 ChangeState(PARSING_CLUSTERS); | 343 ChangeState(kParsingClusters); |
| 314 init_cb_.Run(true, duration); | 344 init_cb_.Run(true, duration); |
| 315 init_cb_.Reset(); | 345 init_cb_.Reset(); |
| 316 | 346 |
| 317 return bytes_parsed; | 347 return bytes_parsed; |
| 318 } | 348 } |
| 319 | 349 |
| 320 int WebMStreamParser::ParseCluster(const uint8* data, int size) { | 350 int WebMStreamParser::ParseCluster(const uint8* data, int size) { |
| 321 if (!cluster_parser_.get()) | 351 if (!cluster_parser_.get()) |
| 322 return -1; | 352 return -1; |
| 323 | 353 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 350 if (!audio_buffers.empty() && !host_->OnAudioBuffers(audio_buffers)) | 380 if (!audio_buffers.empty() && !host_->OnAudioBuffers(audio_buffers)) |
| 351 return -1; | 381 return -1; |
| 352 | 382 |
| 353 if (!video_buffers.empty() && !host_->OnVideoBuffers(video_buffers)) | 383 if (!video_buffers.empty() && !host_->OnVideoBuffers(video_buffers)) |
| 354 return -1; | 384 return -1; |
| 355 | 385 |
| 356 return bytes_parsed; | 386 return bytes_parsed; |
| 357 } | 387 } |
| 358 | 388 |
| 359 } // namespace media | 389 } // namespace media |
| OLD | NEW |