Chromium Code Reviews| Index: media/filters/chunk_demuxer.cc |
| diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
| index f5fcf7dac7c7ca3995256ac9e2b01c4194a6cac5..4dbfac51d2e0bcbd7a3f0b076184575380d4e463 100644 |
| --- a/media/filters/chunk_demuxer.cc |
| +++ b/media/filters/chunk_demuxer.cc |
| @@ -114,6 +114,11 @@ class SourceState { |
| // Aborts the current append sequence and resets the parser. |
| void Abort(); |
| + // Calls Remove(|start|, |end|, |duration|) on all |
| + // ChunkDemuxerStreams managed by this object. |
| + void Remove(base::TimeDelta start, base::TimeDelta end, |
| + base::TimeDelta duration); |
|
xhwang
2013/12/28 01:06:03
Here and in this file, pass base::TimeDelta by con
acolwell GONE FROM CHROMIUM
2013/12/28 02:17:10
I've talked with scherkus@ and fischman@ about thi
xhwang
2013/12/30 17:53:38
sg. thanks for the explanation.
|
| + |
| // Sets |timestamp_offset_| if possible. |
| // Returns if the offset was set. Returns false if the offset could not be |
| // updated at this time. |
| @@ -131,10 +136,18 @@ class SourceState { |
| // end of stream range logic needs to be executed. |
| Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration, bool ended) const; |
| + // Helper methods that call methods with similar names on all the |
| + // ChunkDemuxerStreams managed by this object. |
| void StartReturningData(); |
| void AbortReads(); |
| void Seek(TimeDelta seek_time); |
| void CompletePendingReadIfPossible(); |
| + void OnSetDuration(TimeDelta duration); |
| + void MarkEndOfStream(); |
| + void UnmarkEndOfStream(); |
| + void Shutdown(); |
| + void SetMemoryLimitsForTesting(int memory_limit); |
|
xhwang
2013/12/28 01:06:03
Is |memory_limit| in KB or MB?
acolwell GONE FROM CHROMIUM
2014/01/08 02:16:49
It's bytes. I've added a comment clarifying this h
|
| + bool IsSeekWaitingForData() const; |
| private: |
| // Called by the |stream_parser_| when a new initialization segment is |
| @@ -339,17 +352,9 @@ SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
| } |
| SourceState::~SourceState() { |
| - if (audio_) |
| - audio_->Shutdown(); |
| - |
| - if (video_) |
| - video_->Shutdown(); |
| + Shutdown(); |
| - for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| - itr != text_stream_map_.end(); ++itr) { |
| - itr->second->Shutdown(); |
| - delete itr->second; |
| - } |
| + STLDeleteValues(&text_stream_map_); |
| } |
| void SourceState::Init(const StreamParser::InitCB& init_cb, |
| @@ -401,6 +406,20 @@ void SourceState::Abort() { |
| can_update_offset_ = true; |
| } |
| +void SourceState::Remove(base::TimeDelta start, base::TimeDelta end, |
| + base::TimeDelta duration) { |
| + if (audio_) |
| + audio_->Remove(start, end, duration); |
| + |
| + if (video_) |
| + video_->Remove(start, end, duration); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->Remove(start, end, duration); |
| + } |
| +} |
| + |
| Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, |
| bool ended) const { |
| // TODO(acolwell): When we start allowing disabled tracks we'll need to update |
| @@ -473,6 +492,87 @@ void SourceState::CompletePendingReadIfPossible() { |
| } |
| } |
| +void SourceState::OnSetDuration(TimeDelta duration) { |
| + if (audio_) |
| + audio_->OnSetDuration(duration); |
| + |
| + if (video_) |
| + video_->OnSetDuration(duration); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->OnSetDuration(duration); |
| + } |
| +} |
| + |
| +void SourceState::MarkEndOfStream() { |
| + if (audio_) |
| + audio_->MarkEndOfStream(); |
| + |
| + if (video_) |
| + video_->MarkEndOfStream(); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->MarkEndOfStream(); |
| + } |
| +} |
| + |
| +void SourceState::UnmarkEndOfStream() { |
| + if (audio_) |
| + audio_->UnmarkEndOfStream(); |
| + |
| + if (video_) |
| + video_->UnmarkEndOfStream(); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->UnmarkEndOfStream(); |
| + } |
| +} |
| + |
| +void SourceState::Shutdown() { |
| + if (audio_) |
| + audio_->Shutdown(); |
| + |
| + if (video_) |
| + video_->Shutdown(); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->Shutdown(); |
| + } |
| +} |
| + |
| +void SourceState::SetMemoryLimitsForTesting(int memory_limit) { |
| + if (audio_) |
| + audio_->set_memory_limit_for_testing(memory_limit); |
| + |
| + if (video_) |
| + video_->set_memory_limit_for_testing(memory_limit); |
| + |
| + for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + itr->second->set_memory_limit_for_testing(memory_limit); |
| + } |
| +} |
| + |
| +bool SourceState::IsSeekWaitingForData() const { |
| + if (audio_ && audio_->IsSeekWaitingForData()) |
| + return true; |
| + |
| + if (video_ && video_->IsSeekWaitingForData()) |
| + return true; |
| + |
| + for (TextStreamMap::const_iterator itr = text_stream_map_.begin(); |
| + itr != text_stream_map_.end(); ++itr) { |
| + if (itr->second->IsSeekWaitingForData()) |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| void SourceState::AdjustBufferTimestamps( |
| const StreamParser::BufferQueue& buffers) { |
| if (timestamp_offset_ == TimeDelta()) |
| @@ -1290,11 +1390,9 @@ void ChunkDemuxer::Remove(const std::string& id, base::TimeDelta start, |
| << ", " << end.InSecondsF() << ")"; |
| base::AutoLock auto_lock(lock_); |
| - if (id == source_id_audio_ && audio_) |
| - audio_->Remove(start, end, duration_); |
| - |
| - if (id == source_id_video_ && video_) |
| - video_->Remove(start, end, duration_); |
| + DCHECK(!id.empty()); |
| + CHECK(IsValidId(id)); |
| + source_state_map_[id]->Remove(start, end, duration_); |
| } |
| double ChunkDemuxer::GetDuration() { |
| @@ -1352,11 +1450,10 @@ void ChunkDemuxer::SetDuration(double duration) { |
| duration_ = duration_td; |
| host_->SetDuration(duration_); |
| - if (audio_) |
| - audio_->OnSetDuration(duration_); |
| - |
| - if (video_) |
| - video_->OnSetDuration(duration_); |
| + for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + itr->second->OnSetDuration(duration_); |
| + } |
| } |
| bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { |
| @@ -1382,11 +1479,10 @@ void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) { |
| } |
| bool old_waiting_for_data = IsSeekWaitingForData_Locked(); |
| - if (audio_) |
| - audio_->MarkEndOfStream(); |
| - |
| - if (video_) |
| - video_->MarkEndOfStream(); |
| + for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + itr->second->MarkEndOfStream(); |
| + } |
| CompletePendingReadsIfPossible(); |
| @@ -1412,11 +1508,10 @@ void ChunkDemuxer::UnmarkEndOfStream() { |
| ChangeState_Locked(INITIALIZED); |
| - if (audio_) |
| - audio_->UnmarkEndOfStream(); |
| - |
| - if (video_) |
| - video_->UnmarkEndOfStream(); |
| + for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + itr->second->UnmarkEndOfStream(); |
| + } |
| } |
| void ChunkDemuxer::SetAppendWindowStart(const std::string& id, |
| @@ -1442,11 +1537,7 @@ void ChunkDemuxer::Shutdown() { |
| if (state_ == SHUTDOWN) |
| return; |
| - if (audio_) |
| - audio_->Shutdown(); |
| - |
| - if (video_) |
| - video_->Shutdown(); |
| + ShutdownAllStreams(); |
| ChangeState_Locked(SHUTDOWN); |
| @@ -1455,11 +1546,10 @@ void ChunkDemuxer::Shutdown() { |
| } |
| void ChunkDemuxer::SetMemoryLimitsForTesting(int memory_limit) { |
| - if (audio_) |
| - audio_->set_memory_limit_for_testing(memory_limit); |
| - |
| - if (video_) |
| - video_->set_memory_limit_for_testing(memory_limit); |
| + for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + itr->second->SetMemoryLimitsForTesting(memory_limit); |
| + } |
| } |
| void ChunkDemuxer::ChangeState_Locked(State new_state) { |
| @@ -1471,11 +1561,8 @@ void ChunkDemuxer::ChangeState_Locked(State new_state) { |
| ChunkDemuxer::~ChunkDemuxer() { |
| DCHECK_NE(state_, INITIALIZED); |
| - for (SourceStateMap::iterator it = source_state_map_.begin(); |
| - it != source_state_map_.end(); ++it) { |
| - delete it->second; |
| - } |
| - source_state_map_.clear(); |
| + |
| + STLDeleteValues(&source_state_map_); |
| } |
| void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { |
| @@ -1493,11 +1580,7 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { |
| if (!seek_cb_.is_null()) |
| std::swap(cb, seek_cb_); |
| - if (audio_) |
| - audio_->Shutdown(); |
| - |
| - if (video_) |
| - video_->Shutdown(); |
| + ShutdownAllStreams(); |
| } |
| if (!cb.is_null()) { |
| @@ -1511,15 +1594,14 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { |
| bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { |
| lock_.AssertAcquired(); |
| - bool waiting_for_data = false; |
| - |
| - if (audio_) |
| - waiting_for_data = audio_->IsSeekWaitingForData(); |
| - if (!waiting_for_data && video_) |
| - waiting_for_data = video_->IsSeekWaitingForData(); |
| + for (SourceStateMap::const_iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + if (itr->second->IsSeekWaitingForData()) |
| + return true; |
| + } |
| - return waiting_for_data; |
| + return false; |
| } |
| void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) { |
| @@ -1672,4 +1754,11 @@ void ChunkDemuxer::CompletePendingReadsIfPossible() { |
| } |
| } |
| +void ChunkDemuxer::ShutdownAllStreams() { |
| + for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| + itr != source_state_map_.end(); ++itr) { |
| + itr->second->Shutdown(); |
| + } |
| +} |
| + |
| } // namespace media |