Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(968)

Side by Side Diff: media/filters/chunk_demuxer.cc

Issue 1008463002: Fix MSE GC, make it less aggressive, more spec-compliant (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use newDataSize in SourceBufferStream::GarbageCollectIfNeeded Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698