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 <limits> | 8 #include <limits> |
9 #include <list> | 9 #include <list> |
10 | 10 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 | 126 |
127 // Aborts the current append sequence and resets the parser. | 127 // Aborts the current append sequence and resets the parser. |
128 void Abort(TimeDelta append_window_start, | 128 void Abort(TimeDelta append_window_start, |
129 TimeDelta append_window_end, | 129 TimeDelta append_window_end, |
130 TimeDelta* timestamp_offset); | 130 TimeDelta* timestamp_offset); |
131 | 131 |
132 // Calls Remove(|start|, |end|, |duration|) on all | 132 // Calls Remove(|start|, |end|, |duration|) on all |
133 // ChunkDemuxerStreams managed by this object. | 133 // ChunkDemuxerStreams managed by this object. |
134 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); | 134 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); |
135 | 135 |
136 // Attempts to perform garbage collection in SourceBuffers associated with | |
137 // this ChunkDemuxer. Returns true if garbage collection was successful. | |
138 // |media_time| parameter should indicate the current playback position, | |
wolenetz
2015/06/04 00:38:56
nit: s/position, if/position. If/
servolk
2015/06/04 03:03:01
Done.
| |
139 // if it's a valid time value, the garbage collection algorithm will make sure | |
140 // to preserve unconsumed data buffers in the range between last read position | |
141 // and the current playback position. | |
142 bool EvictFrames(DecodeTimestamp media_time); | |
143 | |
136 // Returns true if currently parsing a media segment, or false otherwise. | 144 // Returns true if currently parsing a media segment, or false otherwise. |
137 bool parsing_media_segment() const { return parsing_media_segment_; } | 145 bool parsing_media_segment() const { return parsing_media_segment_; } |
138 | 146 |
139 // Sets |frame_processor_|'s sequence mode to |sequence_mode|. | 147 // Sets |frame_processor_|'s sequence mode to |sequence_mode|. |
140 void SetSequenceMode(bool sequence_mode); | 148 void SetSequenceMode(bool sequence_mode); |
141 | 149 |
142 // Signals the coded frame processor to update its group start timestamp to be | 150 // Signals the coded frame processor to update its group start timestamp to be |
143 // |timestamp_offset| if it is in sequence append mode. | 151 // |timestamp_offset| if it is in sequence append mode. |
144 void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset); | 152 void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset); |
145 | 153 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
367 | 375 |
368 if (video_) | 376 if (video_) |
369 video_->Remove(start, end, duration); | 377 video_->Remove(start, end, duration); |
370 | 378 |
371 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 379 for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
372 itr != text_stream_map_.end(); ++itr) { | 380 itr != text_stream_map_.end(); ++itr) { |
373 itr->second->Remove(start, end, duration); | 381 itr->second->Remove(start, end, duration); |
374 } | 382 } |
375 } | 383 } |
376 | 384 |
385 bool SourceState::EvictFrames(DecodeTimestamp media_time) { | |
386 bool success = true; | |
387 | |
388 if(audio_) | |
wolenetz
2015/06/04 00:38:56
nit: spacing
servolk
2015/06/04 03:03:01
Done.
| |
389 success = audio_->EvictFrames(media_time) && success; | |
390 | |
391 if (video_) | |
392 success = video_->EvictFrames(media_time) && success; | |
393 | |
394 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | |
395 itr != text_stream_map_.end(); ++itr) { | |
396 success = itr->second->EvictFrames(media_time) && success; | |
397 } | |
398 | |
399 return success; | |
400 } | |
401 | |
377 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, | 402 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, |
378 bool ended) const { | 403 bool ended) const { |
379 // TODO(acolwell): When we start allowing disabled tracks we'll need to update | 404 // TODO(acolwell): When we start allowing disabled tracks we'll need to update |
380 // this code to only add ranges from active tracks. | 405 // this code to only add ranges from active tracks. |
381 RangesList ranges_list; | 406 RangesList ranges_list; |
382 if (audio_) | 407 if (audio_) |
383 ranges_list.push_back(audio_->GetBufferedRanges(duration)); | 408 ranges_list.push_back(audio_->GetBufferedRanges(duration)); |
384 | 409 |
385 if (video_) | 410 if (video_) |
386 ranges_list.push_back(video_->GetBufferedRanges(duration)); | 411 ranges_list.push_back(video_->GetBufferedRanges(duration)); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
876 | 901 |
877 return true; | 902 return true; |
878 } | 903 } |
879 | 904 |
880 void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end, | 905 void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end, |
881 TimeDelta duration) { | 906 TimeDelta duration) { |
882 base::AutoLock auto_lock(lock_); | 907 base::AutoLock auto_lock(lock_); |
883 stream_->Remove(start, end, duration); | 908 stream_->Remove(start, end, duration); |
884 } | 909 } |
885 | 910 |
911 bool ChunkDemuxerStream::EvictFrames(DecodeTimestamp media_time) { | |
912 base::AutoLock auto_lock(lock_); | |
913 return stream_->GarbageCollectIfNeeded(media_time); | |
914 } | |
915 | |
886 void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) { | 916 void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) { |
887 base::AutoLock auto_lock(lock_); | 917 base::AutoLock auto_lock(lock_); |
888 stream_->OnSetDuration(duration); | 918 stream_->OnSetDuration(duration); |
889 } | 919 } |
890 | 920 |
891 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( | 921 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( |
892 TimeDelta duration) const { | 922 TimeDelta duration) const { |
893 base::AutoLock auto_lock(lock_); | 923 base::AutoLock auto_lock(lock_); |
894 | 924 |
895 if (type_ == TEXT) { | 925 if (type_ == TEXT) { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1099 break; | 1129 break; |
1100 } | 1130 } |
1101 | 1131 |
1102 base::ResetAndReturn(&read_cb_).Run(status, buffer); | 1132 base::ResetAndReturn(&read_cb_).Run(status, buffer); |
1103 } | 1133 } |
1104 | 1134 |
1105 ChunkDemuxer::ChunkDemuxer( | 1135 ChunkDemuxer::ChunkDemuxer( |
1106 const base::Closure& open_cb, | 1136 const base::Closure& open_cb, |
1107 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, | 1137 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, |
1108 const LogCB& log_cb, | 1138 const LogCB& log_cb, |
1139 const GetMediaTimeCB& get_media_time_cb, | |
1109 const scoped_refptr<MediaLog>& media_log, | 1140 const scoped_refptr<MediaLog>& media_log, |
1110 bool splice_frames_enabled) | 1141 bool splice_frames_enabled) |
1111 : state_(WAITING_FOR_INIT), | 1142 : state_(WAITING_FOR_INIT), |
1112 cancel_next_seek_(false), | 1143 cancel_next_seek_(false), |
1113 host_(NULL), | 1144 host_(NULL), |
1114 open_cb_(open_cb), | 1145 open_cb_(open_cb), |
1115 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), | 1146 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), |
1116 enable_text_(false), | 1147 enable_text_(false), |
1117 log_cb_(log_cb), | 1148 log_cb_(log_cb), |
1149 get_media_time_cb_(get_media_time_cb), | |
1118 media_log_(media_log), | 1150 media_log_(media_log), |
1119 duration_(kNoTimestamp()), | 1151 duration_(kNoTimestamp()), |
1120 user_specified_duration_(-1), | 1152 user_specified_duration_(-1), |
1121 liveness_(DemuxerStream::LIVENESS_UNKNOWN), | 1153 liveness_(DemuxerStream::LIVENESS_UNKNOWN), |
1122 splice_frames_enabled_(splice_frames_enabled) { | 1154 splice_frames_enabled_(splice_frames_enabled) { |
1123 DCHECK(!open_cb_.is_null()); | 1155 DCHECK(!open_cb_.is_null()); |
1124 DCHECK(!encrypted_media_init_data_cb_.is_null()); | 1156 DCHECK(!encrypted_media_init_data_cb_.is_null()); |
1125 } | 1157 } |
1126 | 1158 |
1127 void ChunkDemuxer::Initialize( | 1159 void ChunkDemuxer::Initialize( |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1310 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { | 1342 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { |
1311 base::AutoLock auto_lock(lock_); | 1343 base::AutoLock auto_lock(lock_); |
1312 DCHECK(!id.empty()); | 1344 DCHECK(!id.empty()); |
1313 | 1345 |
1314 SourceStateMap::const_iterator itr = source_state_map_.find(id); | 1346 SourceStateMap::const_iterator itr = source_state_map_.find(id); |
1315 | 1347 |
1316 DCHECK(itr != source_state_map_.end()); | 1348 DCHECK(itr != source_state_map_.end()); |
1317 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); | 1349 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); |
1318 } | 1350 } |
1319 | 1351 |
1352 bool ChunkDemuxer::EvictFrames() { | |
1353 DecodeTimestamp current_media_time; | |
1354 if (!get_media_time_cb_.is_null()) { | |
1355 current_media_time = | |
1356 DecodeTimestamp::FromPresentationTime(get_media_time_cb_.Run()); | |
wolenetz
2015/06/04 00:38:57
I'm not convinced the conversion from PTS to DTS i
servolk
2015/06/04 03:03:01
The reason we are converting to DTS here is becaus
wolenetz
2015/06/04 20:06:50
Ok. Thanks for considering this detail. As FYI, th
servolk
2015/06/04 20:22:46
Acknowledged.
| |
1357 } else { | |
1358 current_media_time = kNoDecodeTimestamp(); | |
1359 } | |
1360 | |
1361 bool success = true; | |
1362 for (SourceStateMap::iterator itr = source_state_map_.begin(); | |
1363 itr != source_state_map_.end(); ++itr) { | |
1364 success = itr->second->EvictFrames(current_media_time) && success; | |
1365 } | |
1366 return success; | |
1367 } | |
1368 | |
1320 void ChunkDemuxer::AppendData( | 1369 void ChunkDemuxer::AppendData( |
1321 const std::string& id, | 1370 const std::string& id, |
1322 const uint8* data, | 1371 const uint8* data, |
1323 size_t length, | 1372 size_t length, |
1324 TimeDelta append_window_start, | 1373 TimeDelta append_window_start, |
1325 TimeDelta append_window_end, | 1374 TimeDelta append_window_end, |
1326 TimeDelta* timestamp_offset, | 1375 TimeDelta* timestamp_offset, |
1327 const InitSegmentReceivedCB& init_segment_received_cb) { | 1376 const InitSegmentReceivedCB& init_segment_received_cb) { |
1328 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; | 1377 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; |
1329 | 1378 |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1840 } | 1889 } |
1841 | 1890 |
1842 void ChunkDemuxer::ShutdownAllStreams() { | 1891 void ChunkDemuxer::ShutdownAllStreams() { |
1843 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1892 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1844 itr != source_state_map_.end(); ++itr) { | 1893 itr != source_state_map_.end(); ++itr) { |
1845 itr->second->Shutdown(); | 1894 itr->second->Shutdown(); |
1846 } | 1895 } |
1847 } | 1896 } |
1848 | 1897 |
1849 } // namespace media | 1898 } // namespace media |
OLD | NEW |