Chromium Code Reviews| Index: media/filters/chunk_demuxer.cc |
| diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
| index 51511c8f69ad9dff37773d5d147c54b993211786..2022b46871285e5664a79849081ce00ddbcfa378 100644 |
| --- a/media/filters/chunk_demuxer.cc |
| +++ b/media/filters/chunk_demuxer.cc |
| @@ -131,6 +131,12 @@ class SourceState { |
| // ChunkDemuxerStreams managed by this object. |
| void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); |
| + // If the buffer is full, attempts to try to free up space, as specified in |
| + // the "Coded Frame Eviction Algorithm" in the Media Source Extensions Spec. |
| + // Returns false iff buffer is still full after running eviction. |
| + // https://w3c.github.io/media-source/#sourcebuffer-coded-frame-eviction |
| + bool EvictCodedFrames(DecodeTimestamp media_time, size_t newDataSize); |
| + |
| // Returns true if currently parsing a media segment, or false otherwise. |
| bool parsing_media_segment() const { return parsing_media_segment_; } |
| @@ -369,6 +375,36 @@ void SourceState::Remove(TimeDelta start, TimeDelta end, TimeDelta duration) { |
| } |
| } |
| +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
|
| + size_t newDataSize) { |
| + bool success = true; |
| + |
| + size_t newAudioSize = 0; |
| + size_t newVideoSize = 0; |
| + size_t videoBufferedSize = video_ ? video_->GetBufferedSize() : 0; |
| + 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.
|
| + 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
|
| + newAudioSize = newDataSize - newVideoSize; |
| + } else if (video_) { |
| + newVideoSize = newDataSize; |
| + } else if (audio_) { |
| + newAudioSize = newDataSize; |
| + } |
| + |
|
wolenetz
2015/08/20 23:23:37
Please add some DVLOGs describing newDataSize, new
servolk
2015/08/21 01:32:08
Done.
|
| + if (audio_) |
| + success = audio_->EvictCodedFrames(media_time, newAudioSize) && success; |
| + |
| + if (video_) |
| + success = video_->EvictCodedFrames(media_time, newVideoSize) && success; |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + success = itr->second->EvictCodedFrames(media_time, 0) && success; |
| + } |
| + |
| + return success; |
| +} |
| + |
| Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, |
| bool ended) const { |
| // TODO(acolwell): When we start allowing disabled tracks we'll need to update |
| @@ -879,6 +915,12 @@ void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end, |
| stream_->Remove(start, end, duration); |
| } |
| +bool ChunkDemuxerStream::EvictCodedFrames(DecodeTimestamp media_time, |
| + size_t newDataSize) { |
| + base::AutoLock auto_lock(lock_); |
| + return stream_->GarbageCollectIfNeeded(media_time, newDataSize); |
| +} |
| + |
| void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) { |
| base::AutoLock auto_lock(lock_); |
| stream_->OnSetDuration(duration); |
| @@ -915,6 +957,10 @@ TimeDelta ChunkDemuxerStream::GetBufferedDuration() const { |
| return stream_->GetBufferedDuration(); |
| } |
| +size_t ChunkDemuxerStream::GetBufferedSize() const { |
| + return stream_->GetBufferedSize(); |
| +} |
| + |
| void ChunkDemuxerStream::OnNewMediaSegment(DecodeTimestamp start_timestamp) { |
| DVLOG(2) << "ChunkDemuxerStream::OnNewMediaSegment(" |
| << start_timestamp.InSecondsF() << ")"; |
| @@ -1321,6 +1367,29 @@ Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { |
| return itr->second->GetBufferedRanges(duration_, state_ == ENDED); |
| } |
| +bool ChunkDemuxer::EvictCodedFrames(const std::string& id, |
| + base::TimeDelta currentMediaTime, |
| + size_t newDataSize) { |
| + DVLOG(1) << __FUNCTION__ << "(" << id << ")" |
| + << " media_time=" << currentMediaTime.InSecondsF() |
| + << " newDataSize=" << newDataSize; |
| + base::AutoLock auto_lock(lock_); |
| + |
| + // Note: The direct conversion from PTS to DTS is safe here, since we don't |
| + // need to know currentTime precisely for GC. GC only needs to know which GOP |
| + // currentTime points to. |
| + DecodeTimestamp media_time_dts = |
| + DecodeTimestamp::FromPresentationTime(currentMediaTime); |
| + |
| + DCHECK(!id.empty()); |
| + SourceStateMap::const_iterator itr = source_state_map_.find(id); |
| + if (itr == source_state_map_.end()) { |
| + LOG(WARNING) << __FUNCTION__ << " stream " << id << " not found"; |
| + return false; |
| + } |
| + return itr->second->EvictCodedFrames(media_time_dts, newDataSize); |
| +} |
| + |
| void ChunkDemuxer::AppendData( |
| const std::string& id, |
| const uint8* data, |