| 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/filters/chunk_demuxer.h" | 5 #include "media/filters/chunk_demuxer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 // Signal to the stream that buffers handed in through subsequent calls to | 153 // Signal to the stream that buffers handed in through subsequent calls to |
| 154 // Append() belong to a media segment that starts at |start_timestamp|. | 154 // Append() belong to a media segment that starts at |start_timestamp|. |
| 155 void OnNewMediaSegment(TimeDelta start_timestamp); | 155 void OnNewMediaSegment(TimeDelta start_timestamp); |
| 156 | 156 |
| 157 // Called when midstream config updates occur. | 157 // Called when midstream config updates occur. |
| 158 // Returns true if the new config is accepted. | 158 // Returns true if the new config is accepted. |
| 159 // Returns false if the new config should trigger an error. | 159 // Returns false if the new config should trigger an error. |
| 160 bool UpdateAudioConfig(const AudioDecoderConfig& config, const LogCB& log_cb); | 160 bool UpdateAudioConfig(const AudioDecoderConfig& config, const LogCB& log_cb); |
| 161 bool UpdateVideoConfig(const VideoDecoderConfig& config, const LogCB& log_cb); | 161 bool UpdateVideoConfig(const VideoDecoderConfig& config, const LogCB& log_cb); |
| 162 | 162 |
| 163 void EndOfStream(); | 163 void MarkEndOfStream(); |
| 164 void CancelEndOfStream(); | 164 void UnmarkEndOfStream(); |
| 165 | 165 |
| 166 // DemuxerStream methods. | 166 // DemuxerStream methods. |
| 167 virtual void Read(const ReadCB& read_cb) OVERRIDE; | 167 virtual void Read(const ReadCB& read_cb) OVERRIDE; |
| 168 virtual Type type() OVERRIDE; | 168 virtual Type type() OVERRIDE; |
| 169 virtual void EnableBitstreamConverter() OVERRIDE; | 169 virtual void EnableBitstreamConverter() OVERRIDE; |
| 170 virtual AudioDecoderConfig audio_decoder_config() OVERRIDE; | 170 virtual AudioDecoderConfig audio_decoder_config() OVERRIDE; |
| 171 virtual VideoDecoderConfig video_decoder_config() OVERRIDE; | 171 virtual VideoDecoderConfig video_decoder_config() OVERRIDE; |
| 172 | 172 |
| 173 void set_memory_limit_for_testing(int memory_limit) { | 173 void set_memory_limit_for_testing(int memory_limit) { |
| 174 stream_->set_memory_limit_for_testing(memory_limit); | 174 stream_->set_memory_limit_for_testing(memory_limit); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 | 525 |
| 526 if (!stream_) { | 526 if (!stream_) { |
| 527 DCHECK_EQ(state_, UNINITIALIZED); | 527 DCHECK_EQ(state_, UNINITIALIZED); |
| 528 stream_.reset(new SourceBufferStream(config, log_cb)); | 528 stream_.reset(new SourceBufferStream(config, log_cb)); |
| 529 return true; | 529 return true; |
| 530 } | 530 } |
| 531 | 531 |
| 532 return stream_->UpdateVideoConfig(config); | 532 return stream_->UpdateVideoConfig(config); |
| 533 } | 533 } |
| 534 | 534 |
| 535 void ChunkDemuxerStream::EndOfStream() { | 535 void ChunkDemuxerStream::MarkEndOfStream() { |
| 536 base::AutoLock auto_lock(lock_); | 536 base::AutoLock auto_lock(lock_); |
| 537 stream_->EndOfStream(); | 537 stream_->MarkEndOfStream(); |
| 538 } | 538 } |
| 539 | 539 |
| 540 void ChunkDemuxerStream::CancelEndOfStream() { | 540 void ChunkDemuxerStream::UnmarkEndOfStream() { |
| 541 base::AutoLock auto_lock(lock_); | 541 base::AutoLock auto_lock(lock_); |
| 542 stream_->CancelEndOfStream(); | 542 stream_->UnmarkEndOfStream(); |
| 543 } | 543 } |
| 544 | 544 |
| 545 // DemuxerStream methods. | 545 // DemuxerStream methods. |
| 546 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { | 546 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { |
| 547 base::AutoLock auto_lock(lock_); | 547 base::AutoLock auto_lock(lock_); |
| 548 DCHECK_NE(state_, UNINITIALIZED); | 548 DCHECK_NE(state_, UNINITIALIZED); |
| 549 DCHECK(read_cb_.is_null()); | 549 DCHECK(read_cb_.is_null()); |
| 550 | 550 |
| 551 read_cb_ = BindToCurrentLoop(read_cb); | 551 read_cb_ = BindToCurrentLoop(read_cb); |
| 552 CompletePendingReadIfPossible_Locked(); | 552 CompletePendingReadIfPossible_Locked(); |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 const uint8* data, | 875 const uint8* data, |
| 876 size_t length) { | 876 size_t length) { |
| 877 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; | 877 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; |
| 878 | 878 |
| 879 DCHECK(!id.empty()); | 879 DCHECK(!id.empty()); |
| 880 | 880 |
| 881 Ranges<TimeDelta> ranges; | 881 Ranges<TimeDelta> ranges; |
| 882 | 882 |
| 883 { | 883 { |
| 884 base::AutoLock auto_lock(lock_); | 884 base::AutoLock auto_lock(lock_); |
| 885 DCHECK_NE(state_, ENDED); |
| 885 | 886 |
| 886 // Capture if any of the SourceBuffers are waiting for data before we start | 887 // Capture if any of the SourceBuffers are waiting for data before we start |
| 887 // parsing. | 888 // parsing. |
| 888 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); | 889 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); |
| 889 | 890 |
| 890 if (state_ == ENDED) { | |
| 891 ChangeState_Locked(INITIALIZED); | |
| 892 | |
| 893 if (audio_) | |
| 894 audio_->CancelEndOfStream(); | |
| 895 | |
| 896 if (video_) | |
| 897 video_->CancelEndOfStream(); | |
| 898 } | |
| 899 | |
| 900 if (length == 0u) | 891 if (length == 0u) |
| 901 return; | 892 return; |
| 902 | 893 |
| 903 DCHECK(data); | 894 DCHECK(data); |
| 904 | 895 |
| 905 switch (state_) { | 896 switch (state_) { |
| 906 case INITIALIZING: | 897 case INITIALIZING: |
| 907 DCHECK(IsValidId(id)); | 898 DCHECK(IsValidId(id)); |
| 908 if (!source_state_map_[id]->Append(data, length)) { | 899 if (!source_state_map_[id]->Append(data, length)) { |
| 909 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | 900 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 } | 1006 } |
| 1016 | 1007 |
| 1017 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { | 1008 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { |
| 1018 base::AutoLock auto_lock(lock_); | 1009 base::AutoLock auto_lock(lock_); |
| 1019 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; | 1010 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; |
| 1020 CHECK(IsValidId(id)); | 1011 CHECK(IsValidId(id)); |
| 1021 | 1012 |
| 1022 return source_state_map_[id]->SetTimestampOffset(offset); | 1013 return source_state_map_[id]->SetTimestampOffset(offset); |
| 1023 } | 1014 } |
| 1024 | 1015 |
| 1025 void ChunkDemuxer::EndOfStream(PipelineStatus status) { | 1016 void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) { |
| 1026 DVLOG(1) << "EndOfStream(" << status << ")"; | 1017 DVLOG(1) << "MarkEndOfStream(" << status << ")"; |
| 1027 base::AutoLock auto_lock(lock_); | 1018 base::AutoLock auto_lock(lock_); |
| 1028 DCHECK_NE(state_, WAITING_FOR_INIT); | 1019 DCHECK_NE(state_, WAITING_FOR_INIT); |
| 1029 DCHECK_NE(state_, ENDED); | 1020 DCHECK_NE(state_, ENDED); |
| 1030 | 1021 |
| 1031 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) | 1022 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) |
| 1032 return; | 1023 return; |
| 1033 | 1024 |
| 1034 if (state_ == INITIALIZING) { | 1025 if (state_ == INITIALIZING) { |
| 1035 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | 1026 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
| 1036 return; | 1027 return; |
| 1037 } | 1028 } |
| 1038 | 1029 |
| 1039 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); | 1030 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); |
| 1040 if (audio_) | 1031 if (audio_) |
| 1041 audio_->EndOfStream(); | 1032 audio_->MarkEndOfStream(); |
| 1042 | 1033 |
| 1043 if (video_) | 1034 if (video_) |
| 1044 video_->EndOfStream(); | 1035 video_->MarkEndOfStream(); |
| 1045 | 1036 |
| 1046 CompletePendingReadsIfPossible(); | 1037 CompletePendingReadsIfPossible(); |
| 1047 | 1038 |
| 1048 // Give a chance to resume the pending seek process. | 1039 // Give a chance to resume the pending seek process. |
| 1049 if (status != PIPELINE_OK) { | 1040 if (status != PIPELINE_OK) { |
| 1050 ReportError_Locked(status); | 1041 ReportError_Locked(status); |
| 1051 return; | 1042 return; |
| 1052 } | 1043 } |
| 1053 | 1044 |
| 1054 ChangeState_Locked(ENDED); | 1045 ChangeState_Locked(ENDED); |
| 1055 DecreaseDurationIfNecessary(); | 1046 DecreaseDurationIfNecessary(); |
| 1056 | 1047 |
| 1057 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() && | 1048 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() && |
| 1058 !seek_cb_.is_null()) { | 1049 !seek_cb_.is_null()) { |
| 1059 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 1050 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
| 1060 } | 1051 } |
| 1061 } | 1052 } |
| 1062 | 1053 |
| 1054 void ChunkDemuxer::UnmarkEndOfStream() { |
| 1055 DVLOG(1) << "UnmarkEndOfStream()"; |
| 1056 base::AutoLock auto_lock(lock_); |
| 1057 DCHECK_EQ(state_, ENDED); |
| 1058 |
| 1059 ChangeState_Locked(INITIALIZED); |
| 1060 |
| 1061 if (audio_) |
| 1062 audio_->UnmarkEndOfStream(); |
| 1063 |
| 1064 if (video_) |
| 1065 video_->UnmarkEndOfStream(); |
| 1066 } |
| 1067 |
| 1063 void ChunkDemuxer::Shutdown() { | 1068 void ChunkDemuxer::Shutdown() { |
| 1064 DVLOG(1) << "Shutdown()"; | 1069 DVLOG(1) << "Shutdown()"; |
| 1065 base::AutoLock auto_lock(lock_); | 1070 base::AutoLock auto_lock(lock_); |
| 1066 | 1071 |
| 1067 if (state_ == SHUTDOWN) | 1072 if (state_ == SHUTDOWN) |
| 1068 return; | 1073 return; |
| 1069 | 1074 |
| 1070 if (audio_) | 1075 if (audio_) |
| 1071 audio_->Shutdown(); | 1076 audio_->Shutdown(); |
| 1072 | 1077 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 | 1316 |
| 1312 void ChunkDemuxer::CompletePendingReadsIfPossible() { | 1317 void ChunkDemuxer::CompletePendingReadsIfPossible() { |
| 1313 if (audio_) | 1318 if (audio_) |
| 1314 audio_->CompletePendingReadIfPossible(); | 1319 audio_->CompletePendingReadIfPossible(); |
| 1315 | 1320 |
| 1316 if (video_) | 1321 if (video_) |
| 1317 video_->CompletePendingReadIfPossible(); | 1322 video_->CompletePendingReadIfPossible(); |
| 1318 } | 1323 } |
| 1319 | 1324 |
| 1320 } // namespace media | 1325 } // namespace media |
| OLD | NEW |