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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 150 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
151 typedef std::deque<ReadCB> ReadCBQueue; | 151 typedef std::deque<ReadCB> ReadCBQueue; |
152 typedef std::deque<base::Closure> ClosureQueue; | 152 typedef std::deque<base::Closure> ClosureQueue; |
153 | 153 |
154 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); | 154 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); |
155 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); | 155 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); |
156 | 156 |
157 void StartWaitingForSeek(); | 157 void StartWaitingForSeek(); |
158 void Seek(TimeDelta time); | 158 void Seek(TimeDelta time); |
159 bool IsSeekPending() const; | 159 bool IsSeekPending() const; |
160 void Flush(); | |
161 | 160 |
162 // Add buffers to this stream. Buffers are stored in SourceBufferStreams, | 161 // Add buffers to this stream. Buffers are stored in SourceBufferStreams, |
163 // which handle ordering and overlap resolution. | 162 // which handle ordering and overlap resolution. |
164 // Returns true if buffers were successfully added. | 163 // Returns true if buffers were successfully added. |
165 bool Append(const StreamParser::BufferQueue& buffers); | 164 bool Append(const StreamParser::BufferQueue& buffers); |
166 | 165 |
167 // Signal to the stream that buffers handed in through subsequent calls to | 166 // Signal to the stream that buffers handed in through subsequent calls to |
168 // Append() belong to a media segment that starts at |start_timestamp|. | 167 // Append() belong to a media segment that starts at |start_timestamp|. |
169 void OnNewMediaSegment(TimeDelta start_timestamp); | 168 void OnNewMediaSegment(TimeDelta start_timestamp); |
170 | 169 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 | 208 |
210 // Specifies the type of the stream (must be AUDIO or VIDEO for now). | 209 // Specifies the type of the stream (must be AUDIO or VIDEO for now). |
211 Type type_; | 210 Type type_; |
212 | 211 |
213 scoped_ptr<SourceBufferStream> stream_; | 212 scoped_ptr<SourceBufferStream> stream_; |
214 | 213 |
215 mutable base::Lock lock_; | 214 mutable base::Lock lock_; |
216 State state_; | 215 State state_; |
217 ReadCBQueue read_cbs_; | 216 ReadCBQueue read_cbs_; |
218 | 217 |
219 // The timestamp of the current media segment being parsed by | |
220 // |stream_parser_|. | |
221 TimeDelta media_segment_start_time_; | |
222 | |
223 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); | 218 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); |
224 }; | 219 }; |
225 | 220 |
226 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) | 221 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) |
227 : type_(AUDIO), | 222 : type_(AUDIO), |
228 state_(RETURNING_DATA_FOR_READS), | 223 state_(RETURNING_DATA_FOR_READS) { |
229 media_segment_start_time_(kNoTimestamp()) { | |
230 stream_.reset(new SourceBufferStream(audio_config)); | 224 stream_.reset(new SourceBufferStream(audio_config)); |
231 } | 225 } |
232 | 226 |
233 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) | 227 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) |
234 : type_(VIDEO), | 228 : type_(VIDEO), |
235 state_(RETURNING_DATA_FOR_READS) { | 229 state_(RETURNING_DATA_FOR_READS) { |
236 stream_.reset(new SourceBufferStream(video_config)); | 230 stream_.reset(new SourceBufferStream(video_config)); |
237 } | 231 } |
238 | 232 |
239 void ChunkDemuxerStream::StartWaitingForSeek() { | 233 void ChunkDemuxerStream::StartWaitingForSeek() { |
(...skipping 19 matching lines...) Expand all Loading... |
259 | 253 |
260 if (state_ == WAITING_FOR_SEEK) | 254 if (state_ == WAITING_FOR_SEEK) |
261 ChangeState_Locked(RETURNING_DATA_FOR_READS); | 255 ChangeState_Locked(RETURNING_DATA_FOR_READS); |
262 } | 256 } |
263 | 257 |
264 bool ChunkDemuxerStream::IsSeekPending() const { | 258 bool ChunkDemuxerStream::IsSeekPending() const { |
265 base::AutoLock auto_lock(lock_); | 259 base::AutoLock auto_lock(lock_); |
266 return stream_->IsSeekPending(); | 260 return stream_->IsSeekPending(); |
267 } | 261 } |
268 | 262 |
269 void ChunkDemuxerStream::Flush() { | |
270 media_segment_start_time_ = kNoTimestamp(); | |
271 } | |
272 | |
273 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) { | 263 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) { |
274 media_segment_start_time_ = start_timestamp; | 264 base::AutoLock auto_lock(lock_); |
| 265 stream_->OnNewMediaSegment(start_timestamp); |
275 } | 266 } |
276 | 267 |
277 bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) { | 268 bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) { |
278 if (buffers.empty()) | 269 if (buffers.empty()) |
279 return false; | 270 return false; |
280 | 271 |
281 ClosureQueue closures; | 272 ClosureQueue closures; |
282 { | 273 { |
283 base::AutoLock auto_lock(lock_); | 274 base::AutoLock auto_lock(lock_); |
284 DCHECK_NE(state_, SHUTDOWN); | 275 DCHECK_NE(state_, SHUTDOWN); |
285 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 276 if (!stream_->Append(buffers)) { |
286 if (!stream_->Append(buffers, media_segment_start_time_)) { | |
287 DVLOG(1) << "ChunkDemuxerStream::Append() : stream append failed"; | 277 DVLOG(1) << "ChunkDemuxerStream::Append() : stream append failed"; |
288 return false; | 278 return false; |
289 } | 279 } |
290 CreateReadDoneClosures_Locked(&closures); | 280 CreateReadDoneClosures_Locked(&closures); |
291 } | 281 } |
292 | 282 |
293 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it) | 283 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it) |
294 it->Run(); | 284 it->Run(); |
295 | 285 |
296 return true; | 286 return true; |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 | 742 |
753 return true; | 743 return true; |
754 } | 744 } |
755 | 745 |
756 void ChunkDemuxer::Abort(const std::string& id) { | 746 void ChunkDemuxer::Abort(const std::string& id) { |
757 DVLOG(1) << "Abort(" << id << ")"; | 747 DVLOG(1) << "Abort(" << id << ")"; |
758 DCHECK(!id.empty()); | 748 DCHECK(!id.empty()); |
759 DCHECK_GT(stream_parser_map_.count(id), 0u); | 749 DCHECK_GT(stream_parser_map_.count(id), 0u); |
760 | 750 |
761 stream_parser_map_[id]->Flush(); | 751 stream_parser_map_[id]->Flush(); |
762 if (audio_ && source_id_audio_ == id) | |
763 audio_->Flush(); | |
764 if (video_ && source_id_video_ == id) | |
765 video_->Flush(); | |
766 } | 752 } |
767 | 753 |
768 bool ChunkDemuxer::EndOfStream(PipelineStatus status) { | 754 bool ChunkDemuxer::EndOfStream(PipelineStatus status) { |
769 DVLOG(1) << "EndOfStream(" << status << ")"; | 755 DVLOG(1) << "EndOfStream(" << status << ")"; |
770 base::AutoLock auto_lock(lock_); | 756 base::AutoLock auto_lock(lock_); |
771 DCHECK_NE(state_, WAITING_FOR_INIT); | 757 DCHECK_NE(state_, WAITING_FOR_INIT); |
772 DCHECK_NE(state_, ENDED); | 758 DCHECK_NE(state_, ENDED); |
773 | 759 |
774 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) | 760 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) |
775 return true; | 761 return true; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 // TODO(vrk): There should be a special case for the first appends where all | 980 // TODO(vrk): There should be a special case for the first appends where all |
995 // streams (for both demuxed and muxed case) begin at the earliest stream | 981 // streams (for both demuxed and muxed case) begin at the earliest stream |
996 // timestamp. (crbug.com/132815) | 982 // timestamp. (crbug.com/132815) |
997 if (audio_ && source_id == source_id_audio_) | 983 if (audio_ && source_id == source_id_audio_) |
998 audio_->OnNewMediaSegment(start_timestamp); | 984 audio_->OnNewMediaSegment(start_timestamp); |
999 if (video_ && source_id == source_id_video_) | 985 if (video_ && source_id == source_id_video_) |
1000 video_->OnNewMediaSegment(start_timestamp); | 986 video_->OnNewMediaSegment(start_timestamp); |
1001 } | 987 } |
1002 | 988 |
1003 } // namespace media | 989 } // namespace media |
OLD | NEW |