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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 | 124 |
125 // Aborts the current append sequence and resets the parser. | 125 // Aborts the current append sequence and resets the parser. |
126 void Abort(TimeDelta append_window_start, | 126 void Abort(TimeDelta append_window_start, |
127 TimeDelta append_window_end, | 127 TimeDelta append_window_end, |
128 TimeDelta* timestamp_offset); | 128 TimeDelta* timestamp_offset); |
129 | 129 |
130 // Calls Remove(|start|, |end|, |duration|) on all | 130 // Calls Remove(|start|, |end|, |duration|) on all |
131 // ChunkDemuxerStreams managed by this object. | 131 // ChunkDemuxerStreams managed by this object. |
132 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); | 132 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); |
133 | 133 |
134 // If the buffer is full, attempts to try to free up space, as specified in | |
135 // the "Coded Frame Eviction Algorithm" in the Media Source Extensions Spec. | |
136 // Returns false iff buffer is still full after running eviction. | |
137 // https://w3c.github.io/media-source/#sourcebuffer-coded-frame-eviction | |
138 bool EvictCodedFrames(DecodeTimestamp media_time, size_t newDataSize); | |
139 | |
134 // Returns true if currently parsing a media segment, or false otherwise. | 140 // Returns true if currently parsing a media segment, or false otherwise. |
135 bool parsing_media_segment() const { return parsing_media_segment_; } | 141 bool parsing_media_segment() const { return parsing_media_segment_; } |
136 | 142 |
137 // Sets |frame_processor_|'s sequence mode to |sequence_mode|. | 143 // Sets |frame_processor_|'s sequence mode to |sequence_mode|. |
138 void SetSequenceMode(bool sequence_mode); | 144 void SetSequenceMode(bool sequence_mode); |
139 | 145 |
140 // Signals the coded frame processor to update its group start timestamp to be | 146 // Signals the coded frame processor to update its group start timestamp to be |
141 // |timestamp_offset| if it is in sequence append mode. | 147 // |timestamp_offset| if it is in sequence append mode. |
142 void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset); | 148 void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset); |
143 | 149 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 | 368 |
363 if (video_) | 369 if (video_) |
364 video_->Remove(start, end, duration); | 370 video_->Remove(start, end, duration); |
365 | 371 |
366 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 372 for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
367 itr != text_stream_map_.end(); ++itr) { | 373 itr != text_stream_map_.end(); ++itr) { |
368 itr->second->Remove(start, end, duration); | 374 itr->second->Remove(start, end, duration); |
369 } | 375 } |
370 } | 376 } |
371 | 377 |
378 bool SourceState::EvictCodedFrames(DecodeTimestamp media_time, | |
wolenetz
2015/08/20 23:23:37
Please extract the heuristic for determining newAu
servolk
2015/08/21 01:32:08
I've extracted the heuristic into a new method in
| |
379 size_t newDataSize) { | |
380 bool success = true; | |
381 | |
382 size_t newAudioSize = 0; | |
383 size_t newVideoSize = 0; | |
384 size_t videoBufferedSize = video_ ? video_->GetBufferedSize() : 0; | |
385 if (audio_ && video_ && videoBufferedSize > 0) { | |
wolenetz
2015/08/20 23:23:37
nit: please add a comment describing this heuristi
servolk
2015/08/21 01:32:08
Done.
| |
386 newVideoSize = newDataSize * audio_->GetBufferedSize() / videoBufferedSize; | |
wolenetz
2015/08/20 23:23:37
This seems incorrect.
[estimated headroom for new
servolk
2015/08/21 01:32:08
Oh, yes, you are right, not sure what I was thinki
| |
387 newAudioSize = newDataSize - newVideoSize; | |
388 } else if (video_) { | |
389 newVideoSize = newDataSize; | |
390 } else if (audio_) { | |
391 newAudioSize = newDataSize; | |
392 } | |
393 | |
wolenetz
2015/08/20 23:23:37
Please add some DVLOGs describing newDataSize, new
servolk
2015/08/21 01:32:08
Done.
| |
394 if (audio_) | |
395 success = audio_->EvictCodedFrames(media_time, newAudioSize) && success; | |
396 | |
397 if (video_) | |
398 success = video_->EvictCodedFrames(media_time, newVideoSize) && success; | |
399 | |
400 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | |
401 itr != text_stream_map_.end(); ++itr) { | |
402 success = itr->second->EvictCodedFrames(media_time, 0) && success; | |
403 } | |
404 | |
405 return success; | |
406 } | |
407 | |
372 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, | 408 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, |
373 bool ended) const { | 409 bool ended) const { |
374 // TODO(acolwell): When we start allowing disabled tracks we'll need to update | 410 // TODO(acolwell): When we start allowing disabled tracks we'll need to update |
375 // this code to only add ranges from active tracks. | 411 // this code to only add ranges from active tracks. |
376 RangesList ranges_list; | 412 RangesList ranges_list; |
377 if (audio_) | 413 if (audio_) |
378 ranges_list.push_back(audio_->GetBufferedRanges(duration)); | 414 ranges_list.push_back(audio_->GetBufferedRanges(duration)); |
379 | 415 |
380 if (video_) | 416 if (video_) |
381 ranges_list.push_back(video_->GetBufferedRanges(duration)); | 417 ranges_list.push_back(video_->GetBufferedRanges(duration)); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 | 908 |
873 return true; | 909 return true; |
874 } | 910 } |
875 | 911 |
876 void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end, | 912 void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end, |
877 TimeDelta duration) { | 913 TimeDelta duration) { |
878 base::AutoLock auto_lock(lock_); | 914 base::AutoLock auto_lock(lock_); |
879 stream_->Remove(start, end, duration); | 915 stream_->Remove(start, end, duration); |
880 } | 916 } |
881 | 917 |
918 bool ChunkDemuxerStream::EvictCodedFrames(DecodeTimestamp media_time, | |
919 size_t newDataSize) { | |
920 base::AutoLock auto_lock(lock_); | |
921 return stream_->GarbageCollectIfNeeded(media_time, newDataSize); | |
922 } | |
923 | |
882 void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) { | 924 void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) { |
883 base::AutoLock auto_lock(lock_); | 925 base::AutoLock auto_lock(lock_); |
884 stream_->OnSetDuration(duration); | 926 stream_->OnSetDuration(duration); |
885 } | 927 } |
886 | 928 |
887 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( | 929 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( |
888 TimeDelta duration) const { | 930 TimeDelta duration) const { |
889 base::AutoLock auto_lock(lock_); | 931 base::AutoLock auto_lock(lock_); |
890 | 932 |
891 if (type_ == TEXT) { | 933 if (type_ == TEXT) { |
(...skipping 16 matching lines...) Expand all Loading... | |
908 // range. | 950 // range. |
909 Ranges<TimeDelta> valid_time_range; | 951 Ranges<TimeDelta> valid_time_range; |
910 valid_time_range.Add(range.start(0), duration); | 952 valid_time_range.Add(range.start(0), duration); |
911 return range.IntersectionWith(valid_time_range); | 953 return range.IntersectionWith(valid_time_range); |
912 } | 954 } |
913 | 955 |
914 TimeDelta ChunkDemuxerStream::GetBufferedDuration() const { | 956 TimeDelta ChunkDemuxerStream::GetBufferedDuration() const { |
915 return stream_->GetBufferedDuration(); | 957 return stream_->GetBufferedDuration(); |
916 } | 958 } |
917 | 959 |
960 size_t ChunkDemuxerStream::GetBufferedSize() const { | |
961 return stream_->GetBufferedSize(); | |
962 } | |
963 | |
918 void ChunkDemuxerStream::OnNewMediaSegment(DecodeTimestamp start_timestamp) { | 964 void ChunkDemuxerStream::OnNewMediaSegment(DecodeTimestamp start_timestamp) { |
919 DVLOG(2) << "ChunkDemuxerStream::OnNewMediaSegment(" | 965 DVLOG(2) << "ChunkDemuxerStream::OnNewMediaSegment(" |
920 << start_timestamp.InSecondsF() << ")"; | 966 << start_timestamp.InSecondsF() << ")"; |
921 base::AutoLock auto_lock(lock_); | 967 base::AutoLock auto_lock(lock_); |
922 stream_->OnNewMediaSegment(start_timestamp); | 968 stream_->OnNewMediaSegment(start_timestamp); |
923 } | 969 } |
924 | 970 |
925 bool ChunkDemuxerStream::UpdateAudioConfig( | 971 bool ChunkDemuxerStream::UpdateAudioConfig( |
926 const AudioDecoderConfig& config, | 972 const AudioDecoderConfig& config, |
927 const scoped_refptr<MediaLog>& media_log) { | 973 const scoped_refptr<MediaLog>& media_log) { |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1314 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { | 1360 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { |
1315 base::AutoLock auto_lock(lock_); | 1361 base::AutoLock auto_lock(lock_); |
1316 DCHECK(!id.empty()); | 1362 DCHECK(!id.empty()); |
1317 | 1363 |
1318 SourceStateMap::const_iterator itr = source_state_map_.find(id); | 1364 SourceStateMap::const_iterator itr = source_state_map_.find(id); |
1319 | 1365 |
1320 DCHECK(itr != source_state_map_.end()); | 1366 DCHECK(itr != source_state_map_.end()); |
1321 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); | 1367 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); |
1322 } | 1368 } |
1323 | 1369 |
1370 bool ChunkDemuxer::EvictCodedFrames(const std::string& id, | |
1371 base::TimeDelta currentMediaTime, | |
1372 size_t newDataSize) { | |
1373 DVLOG(1) << __FUNCTION__ << "(" << id << ")" | |
1374 << " media_time=" << currentMediaTime.InSecondsF() | |
1375 << " newDataSize=" << newDataSize; | |
1376 base::AutoLock auto_lock(lock_); | |
1377 | |
1378 // Note: The direct conversion from PTS to DTS is safe here, since we don't | |
1379 // need to know currentTime precisely for GC. GC only needs to know which GOP | |
1380 // currentTime points to. | |
1381 DecodeTimestamp media_time_dts = | |
1382 DecodeTimestamp::FromPresentationTime(currentMediaTime); | |
1383 | |
1384 DCHECK(!id.empty()); | |
1385 SourceStateMap::const_iterator itr = source_state_map_.find(id); | |
1386 if (itr == source_state_map_.end()) { | |
1387 LOG(WARNING) << __FUNCTION__ << " stream " << id << " not found"; | |
1388 return false; | |
1389 } | |
1390 return itr->second->EvictCodedFrames(media_time_dts, newDataSize); | |
1391 } | |
1392 | |
1324 void ChunkDemuxer::AppendData( | 1393 void ChunkDemuxer::AppendData( |
1325 const std::string& id, | 1394 const std::string& id, |
1326 const uint8* data, | 1395 const uint8* data, |
1327 size_t length, | 1396 size_t length, |
1328 TimeDelta append_window_start, | 1397 TimeDelta append_window_start, |
1329 TimeDelta append_window_end, | 1398 TimeDelta append_window_end, |
1330 TimeDelta* timestamp_offset, | 1399 TimeDelta* timestamp_offset, |
1331 const InitSegmentReceivedCB& init_segment_received_cb) { | 1400 const InitSegmentReceivedCB& init_segment_received_cb) { |
1332 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; | 1401 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; |
1333 | 1402 |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1834 } | 1903 } |
1835 | 1904 |
1836 void ChunkDemuxer::ShutdownAllStreams() { | 1905 void ChunkDemuxer::ShutdownAllStreams() { |
1837 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1906 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1838 itr != source_state_map_.end(); ++itr) { | 1907 itr != source_state_map_.end(); ++itr) { |
1839 itr->second->Shutdown(); | 1908 itr->second->Shutdown(); |
1840 } | 1909 } |
1841 } | 1910 } |
1842 | 1911 |
1843 } // namespace media | 1912 } // namespace media |
OLD | NEW |