| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool MP4StreamParser::Parse(const uint8_t* buf, int size) { | 96 bool MP4StreamParser::Parse(const uint8_t* buf, int size) { |
| 97 DCHECK_NE(state_, kWaitingForInit); | 97 DCHECK_NE(state_, kWaitingForInit); |
| 98 | 98 |
| 99 if (state_ == kError) | 99 if (state_ == kError) |
| 100 return false; | 100 return false; |
| 101 | 101 |
| 102 queue_.Push(buf, size); | 102 queue_.Push(buf, size); |
| 103 | 103 |
| 104 BufferQueue audio_buffers; | 104 BufferQueueMap buffers; |
| 105 BufferQueue video_buffers; | |
| 106 | 105 |
| 107 bool result = false; | 106 bool result = false; |
| 108 bool err = false; | 107 bool err = false; |
| 109 | 108 |
| 110 do { | 109 do { |
| 111 switch (state_) { | 110 switch (state_) { |
| 112 case kWaitingForInit: | 111 case kWaitingForInit: |
| 113 case kError: | 112 case kError: |
| 114 NOTREACHED(); | 113 NOTREACHED(); |
| 115 return false; | 114 return false; |
| 116 | 115 |
| 117 case kParsingBoxes: | 116 case kParsingBoxes: |
| 118 result = ParseBox(&err); | 117 result = ParseBox(&err); |
| 119 break; | 118 break; |
| 120 | 119 |
| 121 case kWaitingForSampleData: | 120 case kWaitingForSampleData: |
| 122 result = HaveEnoughDataToEnqueueSamples(); | 121 result = HaveEnoughDataToEnqueueSamples(); |
| 123 if (result) | 122 if (result) |
| 124 ChangeState(kEmittingSamples); | 123 ChangeState(kEmittingSamples); |
| 125 break; | 124 break; |
| 126 | 125 |
| 127 case kEmittingSamples: | 126 case kEmittingSamples: |
| 128 result = EnqueueSample(&audio_buffers, &video_buffers, &err); | 127 result = EnqueueSample(&buffers, &err); |
| 129 if (result) { | 128 if (result) { |
| 130 int64_t max_clear = runs_->GetMaxClearOffset() + moof_head_; | 129 int64_t max_clear = runs_->GetMaxClearOffset() + moof_head_; |
| 131 err = !ReadAndDiscardMDATsUntil(max_clear); | 130 err = !ReadAndDiscardMDATsUntil(max_clear); |
| 132 } | 131 } |
| 133 break; | 132 break; |
| 134 } | 133 } |
| 135 } while (result && !err); | 134 } while (result && !err); |
| 136 | 135 |
| 137 if (!err) | 136 if (!err) |
| 138 err = !SendAndFlushSamples(&audio_buffers, &video_buffers); | 137 err = !SendAndFlushSamples(&buffers); |
| 139 | 138 |
| 140 if (err) { | 139 if (err) { |
| 141 DLOG(ERROR) << "Error while parsing MP4"; | 140 DLOG(ERROR) << "Error while parsing MP4"; |
| 142 moov_.reset(); | 141 moov_.reset(); |
| 143 Reset(); | 142 Reset(); |
| 144 ChangeState(kError); | 143 ChangeState(kError); |
| 145 return false; | 144 return false; |
| 146 } | 145 } |
| 147 | 146 |
| 148 return true; | 147 return true; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 // not required to use subsample encryption, so we may need to add an entry. | 478 // not required to use subsample encryption, so we may need to add an entry. |
| 480 if (subsamples->empty()) { | 479 if (subsamples->empty()) { |
| 481 subsamples->push_back(SubsampleEntry( | 480 subsamples->push_back(SubsampleEntry( |
| 482 kADTSHeaderMinSize, frame_buf->size() - kADTSHeaderMinSize)); | 481 kADTSHeaderMinSize, frame_buf->size() - kADTSHeaderMinSize)); |
| 483 } else { | 482 } else { |
| 484 (*subsamples)[0].clear_bytes += kADTSHeaderMinSize; | 483 (*subsamples)[0].clear_bytes += kADTSHeaderMinSize; |
| 485 } | 484 } |
| 486 return true; | 485 return true; |
| 487 } | 486 } |
| 488 | 487 |
| 489 bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, | 488 bool MP4StreamParser::EnqueueSample(BufferQueueMap* buffers, bool* err) { |
| 490 BufferQueue* video_buffers, | |
| 491 bool* err) { | |
| 492 DCHECK_EQ(state_, kEmittingSamples); | 489 DCHECK_EQ(state_, kEmittingSamples); |
| 493 | 490 |
| 494 if (!runs_->IsRunValid()) { | 491 if (!runs_->IsRunValid()) { |
| 495 // Flush any buffers we've gotten in this chunk so that buffers don't | 492 // Flush any buffers we've gotten in this chunk so that buffers don't |
| 496 // cross |new_segment_cb_| calls | 493 // cross |new_segment_cb_| calls |
| 497 *err = !SendAndFlushSamples(audio_buffers, video_buffers); | 494 *err = !SendAndFlushSamples(buffers); |
| 498 if (*err) | 495 if (*err) |
| 499 return false; | 496 return false; |
| 500 | 497 |
| 501 // Remain in kEmittingSamples state, discarding data, until the end of | 498 // Remain in kEmittingSamples state, discarding data, until the end of |
| 502 // the current 'mdat' box has been appended to the queue. | 499 // the current 'mdat' box has been appended to the queue. |
| 503 if (!queue_.Trim(mdat_tail_)) | 500 if (!queue_.Trim(mdat_tail_)) |
| 504 return false; | 501 return false; |
| 505 | 502 |
| 506 ChangeState(kParsingBoxes); | 503 ChangeState(kParsingBoxes); |
| 507 end_of_segment_cb_.Run(); | 504 end_of_segment_cb_.Run(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 stream_buf->set_timestamp(runs_->cts()); | 613 stream_buf->set_timestamp(runs_->cts()); |
| 617 stream_buf->SetDecodeTimestamp(runs_->dts()); | 614 stream_buf->SetDecodeTimestamp(runs_->dts()); |
| 618 | 615 |
| 619 DVLOG(3) << "Pushing frame: aud=" << audio | 616 DVLOG(3) << "Pushing frame: aud=" << audio |
| 620 << ", key=" << runs_->is_keyframe() | 617 << ", key=" << runs_->is_keyframe() |
| 621 << ", dur=" << runs_->duration().InMilliseconds() | 618 << ", dur=" << runs_->duration().InMilliseconds() |
| 622 << ", dts=" << runs_->dts().InMilliseconds() | 619 << ", dts=" << runs_->dts().InMilliseconds() |
| 623 << ", cts=" << runs_->cts().InMilliseconds() | 620 << ", cts=" << runs_->cts().InMilliseconds() |
| 624 << ", size=" << runs_->sample_size(); | 621 << ", size=" << runs_->sample_size(); |
| 625 | 622 |
| 626 if (audio) { | 623 (*buffers)[runs_->track_id()].push_back(stream_buf); |
| 627 audio_buffers->push_back(stream_buf); | |
| 628 } else { | |
| 629 video_buffers->push_back(stream_buf); | |
| 630 } | |
| 631 | |
| 632 runs_->AdvanceSample(); | 624 runs_->AdvanceSample(); |
| 633 return true; | 625 return true; |
| 634 } | 626 } |
| 635 | 627 |
| 636 bool MP4StreamParser::SendAndFlushSamples(BufferQueue* audio_buffers, | 628 bool MP4StreamParser::SendAndFlushSamples(BufferQueueMap* buffers) { |
| 637 BufferQueue* video_buffers) { | 629 if (buffers->empty()) |
| 638 if (audio_buffers->empty() && video_buffers->empty()) | |
| 639 return true; | 630 return true; |
| 640 | 631 bool success = new_buffers_cb_.Run(*buffers); |
| 641 TextBufferQueueMap empty_text_map; | 632 buffers->clear(); |
| 642 bool success = new_buffers_cb_.Run(*audio_buffers, | |
| 643 *video_buffers, | |
| 644 empty_text_map); | |
| 645 audio_buffers->clear(); | |
| 646 video_buffers->clear(); | |
| 647 return success; | 633 return success; |
| 648 } | 634 } |
| 649 | 635 |
| 650 bool MP4StreamParser::ReadAndDiscardMDATsUntil(int64_t max_clear_offset) { | 636 bool MP4StreamParser::ReadAndDiscardMDATsUntil(int64_t max_clear_offset) { |
| 651 bool err = false; | 637 bool err = false; |
| 652 int64_t upper_bound = std::min(max_clear_offset, queue_.tail()); | 638 int64_t upper_bound = std::min(max_clear_offset, queue_.tail()); |
| 653 while (mdat_tail_ < upper_bound) { | 639 while (mdat_tail_ < upper_bound) { |
| 654 const uint8_t* buf = NULL; | 640 const uint8_t* buf = NULL; |
| 655 int size = 0; | 641 int size = 0; |
| 656 queue_.PeekAt(mdat_tail_, &buf, &size); | 642 queue_.PeekAt(mdat_tail_, &buf, &size); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 runs.AdvanceSample(); | 693 runs.AdvanceSample(); |
| 708 } | 694 } |
| 709 runs.AdvanceRun(); | 695 runs.AdvanceRun(); |
| 710 } | 696 } |
| 711 | 697 |
| 712 return true; | 698 return true; |
| 713 } | 699 } |
| 714 | 700 |
| 715 } // namespace mp4 | 701 } // namespace mp4 |
| 716 } // namespace media | 702 } // namespace media |
| OLD | NEW |