| 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/mp4/mp4_stream_parser.h" | 5 #include "media/formats/mp4/mp4_stream_parser.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 audio_track_id_(0), | 35 audio_track_id_(0), |
| 36 video_track_id_(0), | 36 video_track_id_(0), |
| 37 audio_object_types_(audio_object_types), | 37 audio_object_types_(audio_object_types), |
| 38 has_sbr_(has_sbr), | 38 has_sbr_(has_sbr), |
| 39 is_audio_track_encrypted_(false), | 39 is_audio_track_encrypted_(false), |
| 40 is_video_track_encrypted_(false) { | 40 is_video_track_encrypted_(false) { |
| 41 } | 41 } |
| 42 | 42 |
| 43 MP4StreamParser::~MP4StreamParser() {} | 43 MP4StreamParser::~MP4StreamParser() {} |
| 44 | 44 |
| 45 void MP4StreamParser::Init(const InitCB& init_cb, | 45 void MP4StreamParser::Init( |
| 46 const NewConfigCB& config_cb, | 46 const InitCB& init_cb, |
| 47 const NewBuffersCB& new_buffers_cb, | 47 const NewConfigCB& config_cb, |
| 48 bool /* ignore_text_tracks */ , | 48 const NewBuffersCB& new_buffers_cb, |
| 49 const NeedKeyCB& need_key_cb, | 49 bool /* ignore_text_tracks */, |
| 50 const NewMediaSegmentCB& new_segment_cb, | 50 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, |
| 51 const base::Closure& end_of_segment_cb, | 51 const NewMediaSegmentCB& new_segment_cb, |
| 52 const LogCB& log_cb) { | 52 const base::Closure& end_of_segment_cb, |
| 53 const LogCB& log_cb) { |
| 53 DCHECK_EQ(state_, kWaitingForInit); | 54 DCHECK_EQ(state_, kWaitingForInit); |
| 54 DCHECK(init_cb_.is_null()); | 55 DCHECK(init_cb_.is_null()); |
| 55 DCHECK(!init_cb.is_null()); | 56 DCHECK(!init_cb.is_null()); |
| 56 DCHECK(!config_cb.is_null()); | 57 DCHECK(!config_cb.is_null()); |
| 57 DCHECK(!new_buffers_cb.is_null()); | 58 DCHECK(!new_buffers_cb.is_null()); |
| 58 DCHECK(!need_key_cb.is_null()); | 59 DCHECK(!encrypted_media_init_data_cb.is_null()); |
| 59 DCHECK(!end_of_segment_cb.is_null()); | 60 DCHECK(!end_of_segment_cb.is_null()); |
| 60 | 61 |
| 61 ChangeState(kParsingBoxes); | 62 ChangeState(kParsingBoxes); |
| 62 init_cb_ = init_cb; | 63 init_cb_ = init_cb; |
| 63 config_cb_ = config_cb; | 64 config_cb_ = config_cb; |
| 64 new_buffers_cb_ = new_buffers_cb; | 65 new_buffers_cb_ = new_buffers_cb; |
| 65 need_key_cb_ = need_key_cb; | 66 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; |
| 66 new_segment_cb_ = new_segment_cb; | 67 new_segment_cb_ = new_segment_cb; |
| 67 end_of_segment_cb_ = end_of_segment_cb; | 68 end_of_segment_cb_ = end_of_segment_cb; |
| 68 log_cb_ = log_cb; | 69 log_cb_ = log_cb; |
| 69 } | 70 } |
| 70 | 71 |
| 71 void MP4StreamParser::Reset() { | 72 void MP4StreamParser::Reset() { |
| 72 queue_.Reset(); | 73 queue_.Reset(); |
| 73 runs_.reset(); | 74 runs_.reset(); |
| 74 moof_head_ = 0; | 75 moof_head_ = 0; |
| 75 mdat_tail_ = 0; | 76 mdat_tail_ = 0; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 moov_->extends.header.fragment_duration, moov_->header.timescale); | 310 moov_->extends.header.fragment_duration, moov_->header.timescale); |
| 310 } else if (moov_->header.duration > 0 && | 311 } else if (moov_->header.duration > 0 && |
| 311 moov_->header.duration != kuint64max) { | 312 moov_->header.duration != kuint64max) { |
| 312 params.duration = | 313 params.duration = |
| 313 TimeDeltaFromRational(moov_->header.duration, moov_->header.timescale); | 314 TimeDeltaFromRational(moov_->header.duration, moov_->header.timescale); |
| 314 } | 315 } |
| 315 | 316 |
| 316 if (!init_cb_.is_null()) | 317 if (!init_cb_.is_null()) |
| 317 base::ResetAndReturn(&init_cb_).Run(true, params); | 318 base::ResetAndReturn(&init_cb_).Run(true, params); |
| 318 | 319 |
| 319 EmitNeedKeyIfNecessary(moov_->pssh); | 320 if (!moov_->pssh.empty()) |
| 321 OnEncryptedMediaInitData(moov_->pssh); |
| 322 |
| 320 return true; | 323 return true; |
| 321 } | 324 } |
| 322 | 325 |
| 323 bool MP4StreamParser::ParseMoof(BoxReader* reader) { | 326 bool MP4StreamParser::ParseMoof(BoxReader* reader) { |
| 324 RCHECK(moov_.get()); // Must already have initialization segment | 327 RCHECK(moov_.get()); // Must already have initialization segment |
| 325 MovieFragment moof; | 328 MovieFragment moof; |
| 326 RCHECK(moof.Parse(reader)); | 329 RCHECK(moof.Parse(reader)); |
| 327 if (!runs_) | 330 if (!runs_) |
| 328 runs_.reset(new TrackRunIterator(moov_.get(), log_cb_)); | 331 runs_.reset(new TrackRunIterator(moov_.get(), log_cb_)); |
| 329 RCHECK(runs_->Init(moof)); | 332 RCHECK(runs_->Init(moof)); |
| 330 RCHECK(ComputeHighestEndOffset(moof)); | 333 RCHECK(ComputeHighestEndOffset(moof)); |
| 331 EmitNeedKeyIfNecessary(moof.pssh); | 334 |
| 335 if (!moof.pssh.empty()) |
| 336 OnEncryptedMediaInitData(moof.pssh); |
| 337 |
| 332 new_segment_cb_.Run(); | 338 new_segment_cb_.Run(); |
| 333 ChangeState(kWaitingForSampleData); | 339 ChangeState(kWaitingForSampleData); |
| 334 return true; | 340 return true; |
| 335 } | 341 } |
| 336 | 342 |
| 337 void MP4StreamParser::EmitNeedKeyIfNecessary( | 343 void MP4StreamParser::OnEncryptedMediaInitData( |
| 338 const std::vector<ProtectionSystemSpecificHeader>& headers) { | 344 const std::vector<ProtectionSystemSpecificHeader>& headers) { |
| 339 // TODO(strobe): ensure that the value of init_data (all PSSH headers | 345 // TODO(strobe): ensure that the value of init_data (all PSSH headers |
| 340 // concatenated in arbitrary order) matches the EME spec. | 346 // concatenated in arbitrary order) matches the EME spec. |
| 341 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=17673. | 347 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=17673. |
| 342 if (headers.empty()) | |
| 343 return; | |
| 344 | |
| 345 size_t total_size = 0; | 348 size_t total_size = 0; |
| 346 for (size_t i = 0; i < headers.size(); i++) | 349 for (size_t i = 0; i < headers.size(); i++) |
| 347 total_size += headers[i].raw_box.size(); | 350 total_size += headers[i].raw_box.size(); |
| 348 | 351 |
| 349 std::vector<uint8> init_data(total_size); | 352 std::vector<uint8> init_data(total_size); |
| 350 size_t pos = 0; | 353 size_t pos = 0; |
| 351 for (size_t i = 0; i < headers.size(); i++) { | 354 for (size_t i = 0; i < headers.size(); i++) { |
| 352 memcpy(&init_data[pos], &headers[i].raw_box[0], | 355 memcpy(&init_data[pos], &headers[i].raw_box[0], |
| 353 headers[i].raw_box.size()); | 356 headers[i].raw_box.size()); |
| 354 pos += headers[i].raw_box.size(); | 357 pos += headers[i].raw_box.size(); |
| 355 } | 358 } |
| 356 need_key_cb_.Run(kCencInitDataType, init_data); | 359 encrypted_media_init_data_cb_.Run(kCencInitDataType, init_data); |
| 357 } | 360 } |
| 358 | 361 |
| 359 bool MP4StreamParser::PrepareAVCBuffer( | 362 bool MP4StreamParser::PrepareAVCBuffer( |
| 360 const AVCDecoderConfigurationRecord& avc_config, | 363 const AVCDecoderConfigurationRecord& avc_config, |
| 361 std::vector<uint8>* frame_buf, | 364 std::vector<uint8>* frame_buf, |
| 362 std::vector<SubsampleEntry>* subsamples) const { | 365 std::vector<SubsampleEntry>* subsamples) const { |
| 363 // Convert the AVC NALU length fields to Annex B headers, as expected by | 366 // Convert the AVC NALU length fields to Annex B headers, as expected by |
| 364 // decoding libraries. Since this may enlarge the size of the buffer, we also | 367 // decoding libraries. Since this may enlarge the size of the buffer, we also |
| 365 // update the clear byte count for each subsample if encryption is used to | 368 // update the clear byte count for each subsample if encryption is used to |
| 366 // account for the difference in size between the length prefix and Annex B | 369 // account for the difference in size between the length prefix and Annex B |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 runs.AdvanceSample(); | 626 runs.AdvanceSample(); |
| 624 } | 627 } |
| 625 runs.AdvanceRun(); | 628 runs.AdvanceRun(); |
| 626 } | 629 } |
| 627 | 630 |
| 628 return true; | 631 return true; |
| 629 } | 632 } |
| 630 | 633 |
| 631 } // namespace mp4 | 634 } // namespace mp4 |
| 632 } // namespace media | 635 } // namespace media |
| OLD | NEW |