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

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

Issue 17408005: Refactored DecoderBuffer to use unix_hacker_style naming. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@localrefactor
Patch Set: Created 7 years, 6 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 <deque> 8 #include <deque>
9 #include <limits> 9 #include <limits>
10 10
(...skipping 30 matching lines...) Expand all
41 // Returns true if the data was successfully appended. Returns false if an 41 // Returns true if the data was successfully appended. Returns false if an
42 // error occurred. 42 // error occurred.
43 bool Append(const uint8* data, size_t length); 43 bool Append(const uint8* data, size_t length);
44 44
45 // Aborts the current append sequence and resets the parser. 45 // Aborts the current append sequence and resets the parser.
46 void Abort(); 46 void Abort();
47 47
48 // Sets |timestamp_offset_| if possible. 48 // Sets |timestamp_offset_| if possible.
49 // Returns if the offset was set. Returns false if the offset could not be 49 // Returns if the offset was set. Returns false if the offset could not be
50 // updated at this time. 50 // updated at this time.
51 bool SetTimestampOffset(TimeDelta timestamp_offset); 51 bool set_timestampOffset(TimeDelta timestamp_offset);
52 52
53 TimeDelta timestamp_offset() const { return timestamp_offset_; } 53 TimeDelta timestamp_offset() const { return timestamp_offset_; }
54 54
55 private: 55 private:
56 // Called by the |stream_parser_| at the beginning of a new media segment. 56 // Called by the |stream_parser_| at the beginning of a new media segment.
57 // |timestamp| is the timestamp on the first buffer in the segment. 57 // |timestamp| is the timestamp on the first buffer in the segment.
58 // It modifies the state of this object and then calls |new_segment_cb| with 58 // It modifies the state of this object and then calls |new_segment_cb| with
59 // modified version of |timestamp|. 59 // modified version of |timestamp|.
60 void OnNewMediaSegment(const StreamParser::NewMediaSegmentCB& new_segment_cb, 60 void OnNewMediaSegment(const StreamParser::NewMediaSegmentCB& new_segment_cb,
61 TimeDelta timestamp); 61 TimeDelta timestamp);
(...skipping 27 matching lines...) Expand all
89 // Keeps track of whether |timestamp_offset_| can be modified. 89 // Keeps track of whether |timestamp_offset_| can be modified.
90 bool can_update_offset_; 90 bool can_update_offset_;
91 91
92 // The object used to parse appended data. 92 // The object used to parse appended data.
93 scoped_ptr<StreamParser> stream_parser_; 93 scoped_ptr<StreamParser> stream_parser_;
94 94
95 DISALLOW_COPY_AND_ASSIGN(SourceState); 95 DISALLOW_COPY_AND_ASSIGN(SourceState);
96 }; 96 };
97 97
98 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser) 98 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser)
99 : can_update_offset_(true), 99 : can_update_offset_(true), stream_parser_(stream_parser.release()) {}
100 stream_parser_(stream_parser.release()) {
101 }
102 100
103 void SourceState::Init(const StreamParser::InitCB& init_cb, 101 void SourceState::Init(const StreamParser::InitCB& init_cb,
104 const StreamParser::NewConfigCB& config_cb, 102 const StreamParser::NewConfigCB& config_cb,
105 const StreamParser::NewBuffersCB& audio_cb, 103 const StreamParser::NewBuffersCB& audio_cb,
106 const StreamParser::NewBuffersCB& video_cb, 104 const StreamParser::NewBuffersCB& video_cb,
107 const StreamParser::NewTextBuffersCB& text_cb, 105 const StreamParser::NewTextBuffersCB& text_cb,
108 const StreamParser::NeedKeyCB& need_key_cb, 106 const StreamParser::NeedKeyCB& need_key_cb,
109 const AddTextTrackCB& add_text_track_cb, 107 const AddTextTrackCB& add_text_track_cb,
110 const StreamParser::NewMediaSegmentCB& new_segment_cb, 108 const StreamParser::NewMediaSegmentCB& new_segment_cb,
111 const LogCB& log_cb) { 109 const LogCB& log_cb) {
112 stream_parser_->Init(init_cb, config_cb, 110 stream_parser_->Init(
113 base::Bind(&SourceState::OnBuffers, 111 init_cb, config_cb,
114 base::Unretained(this), audio_cb), 112 base::Bind(&SourceState::OnBuffers, base::Unretained(this), audio_cb),
115 base::Bind(&SourceState::OnBuffers, 113 base::Bind(&SourceState::OnBuffers, base::Unretained(this), video_cb),
116 base::Unretained(this), video_cb), 114 base::Bind(&SourceState::OnTextBuffers, base::Unretained(this), text_cb),
117 base::Bind(&SourceState::OnTextBuffers, 115 need_key_cb, add_text_track_cb,
118 base::Unretained(this), text_cb), 116 base::Bind(&SourceState::OnNewMediaSegment, base::Unretained(this),
119 need_key_cb, 117 new_segment_cb),
120 add_text_track_cb, 118 base::Bind(&SourceState::OnEndOfMediaSegment, base::Unretained(this)),
121 base::Bind(&SourceState::OnNewMediaSegment, 119 log_cb);
122 base::Unretained(this), new_segment_cb),
123 base::Bind(&SourceState::OnEndOfMediaSegment,
124 base::Unretained(this)),
125 log_cb);
126 } 120 }
127 121
128 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { 122 bool SourceState::set_timestampOffset(TimeDelta timestamp_offset) {
129 if (!can_update_offset_) 123 if (!can_update_offset_) return false;
130 return false;
131 124
132 timestamp_offset_ = timestamp_offset; 125 timestamp_offset_ = timestamp_offset;
133 return true; 126 return true;
134 } 127 }
135 128
136 bool SourceState::Append(const uint8* data, size_t length) { 129 bool SourceState::Append(const uint8* data, size_t length) {
137 return stream_parser_->Parse(data, length); 130 return stream_parser_->Parse(data, length);
138 } 131 }
139 132
140 void SourceState::Abort() { 133 void SourceState::Abort() {
141 stream_parser_->Flush(); 134 stream_parser_->Flush();
142 can_update_offset_ = true; 135 can_update_offset_ = true;
143 } 136 }
144 137
145 void SourceState::AdjustBufferTimestamps( 138 void SourceState::AdjustBufferTimestamps(
146 const StreamParser::BufferQueue& buffers) { 139 const StreamParser::BufferQueue& buffers) {
147 if (timestamp_offset_ == TimeDelta()) 140 if (timestamp_offset_ == TimeDelta()) return;
148 return;
149 141
150 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); 142 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
151 itr != buffers.end(); ++itr) { 143 itr != buffers.end(); ++itr) {
152 (*itr)->SetDecodeTimestamp( 144 (*itr)
153 (*itr)->GetDecodeTimestamp() + timestamp_offset_); 145 ->SetDecodeTimestamp((*itr)->GetDecodeTimestamp() + timestamp_offset_);
154 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset_); 146 (*itr)->set_timestamp((*itr)->get_timestamp() + timestamp_offset_);
155 } 147 }
156 } 148 }
157 149
158 void SourceState::OnNewMediaSegment( 150 void SourceState::OnNewMediaSegment(
159 const StreamParser::NewMediaSegmentCB& new_segment_cb, 151 const StreamParser::NewMediaSegmentCB& new_segment_cb,
160 TimeDelta timestamp) { 152 TimeDelta timestamp) {
161 DCHECK(timestamp != kNoTimestamp()); 153 DCHECK(timestamp != kNoTimestamp());
162 DVLOG(2) << "OnNewMediaSegment(" << timestamp.InSecondsF() << ")"; 154 DVLOG(2) << "OnNewMediaSegment(" << timestamp.InSecondsF() << ")";
163 155
164 can_update_offset_ = false; 156 can_update_offset_ = false;
165 new_segment_cb.Run(timestamp + timestamp_offset_); 157 new_segment_cb.Run(timestamp + timestamp_offset_);
166 } 158 }
167 159
168 void SourceState::OnEndOfMediaSegment() { 160 void SourceState::OnEndOfMediaSegment() {
169 DVLOG(2) << "OnEndOfMediaSegment()"; 161 DVLOG(2) << "OnEndOfMediaSegment()";
170 can_update_offset_ = true; 162 can_update_offset_ = true;
171 } 163 }
172 164
173 bool SourceState::OnBuffers(const StreamParser::NewBuffersCB& new_buffers_cb, 165 bool SourceState::OnBuffers(const StreamParser::NewBuffersCB& new_buffers_cb,
174 const StreamParser::BufferQueue& buffers) { 166 const StreamParser::BufferQueue& buffers) {
175 if (new_buffers_cb.is_null()) 167 if (new_buffers_cb.is_null()) return false;
176 return false;
177 168
178 AdjustBufferTimestamps(buffers); 169 AdjustBufferTimestamps(buffers);
179 170
180 return new_buffers_cb.Run(buffers); 171 return new_buffers_cb.Run(buffers);
181 } 172 }
182 173
183 bool SourceState::OnTextBuffers( 174 bool SourceState::OnTextBuffers(
184 const StreamParser::NewTextBuffersCB& new_buffers_cb, 175 const StreamParser::NewTextBuffersCB& new_buffers_cb, TextTrack* text_track,
185 TextTrack* text_track,
186 const StreamParser::BufferQueue& buffers) { 176 const StreamParser::BufferQueue& buffers) {
187 if (new_buffers_cb.is_null()) 177 if (new_buffers_cb.is_null()) return false;
188 return false;
189 178
190 AdjustBufferTimestamps(buffers); 179 AdjustBufferTimestamps(buffers);
191 180
192 return new_buffers_cb.Run(text_track, buffers); 181 return new_buffers_cb.Run(text_track, buffers);
193 } 182 }
194 183
195 class ChunkDemuxerStream : public DemuxerStream { 184 class ChunkDemuxerStream : public DemuxerStream {
196 public: 185 public:
197 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; 186 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
198 typedef std::deque<ReadCB> ReadCBQueue; 187 typedef std::deque<ReadCB> ReadCBQueue;
199 typedef std::deque<base::Closure> ClosureQueue; 188 typedef std::deque<base::Closure> ClosureQueue;
200 189
201 ChunkDemuxerStream(const AudioDecoderConfig& audio_config, 190 ChunkDemuxerStream(const AudioDecoderConfig& audio_config,
202 const LogCB& log_cb); 191 const LogCB& log_cb);
203 ChunkDemuxerStream(const VideoDecoderConfig& video_config, 192 ChunkDemuxerStream(const VideoDecoderConfig& video_config,
204 const LogCB& log_cb); 193 const LogCB& log_cb);
205 virtual ~ChunkDemuxerStream(); 194 virtual ~ChunkDemuxerStream();
206 195
207 void StartWaitingForSeek(); 196 void StartWaitingForSeek();
208 void Seek(TimeDelta time); 197 void Seek(TimeDelta time);
209 void CancelPendingSeek(); 198 void CancelPendingSeek();
210 bool IsSeekPending() const; 199 bool IsSeekPending() const;
211 200
212 // Add buffers to this stream. Buffers are stored in SourceBufferStreams, 201 // Add buffers to this stream. Buffers are stored in SourceBufferStreams,
213 // which handle ordering and overlap resolution. 202 // which handle ordering and overlap resolution.
214 // Returns true if buffers were successfully added. 203 // Returns true if buffers were successfully added.
215 bool Append(const StreamParser::BufferQueue& buffers); 204 bool Append(const StreamParser::BufferQueue& buffers);
216 205
217 // Signal to the stream that duration has changed to |duration|. 206 // Signal to the stream that duration has changed to |duration|.
218 void OnSetDuration(base::TimeDelta duration); 207 void Onset_duration(base::TimeDelta duration);
219 208
220 // Returns the range of buffered data in this stream, capped at |duration|. 209 // Returns the range of buffered data in this stream, capped at |duration|.
221 Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const; 210 Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const;
222 211
223 // Signal to the stream that buffers handed in through subsequent calls to 212 // Signal to the stream that buffers handed in through subsequent calls to
224 // Append() belong to a media segment that starts at |start_timestamp|. 213 // Append() belong to a media segment that starts at |start_timestamp|.
225 void OnNewMediaSegment(TimeDelta start_timestamp); 214 void OnNewMediaSegment(TimeDelta start_timestamp);
226 215
227 // Called when midstream config updates occur. 216 // Called when midstream config updates occur.
228 // Returns true if the new config is accepted. 217 // Returns true if the new config is accepted.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 263
275 mutable base::Lock lock_; 264 mutable base::Lock lock_;
276 State state_; 265 State state_;
277 ReadCBQueue read_cbs_; 266 ReadCBQueue read_cbs_;
278 267
279 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); 268 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream);
280 }; 269 };
281 270
282 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config, 271 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config,
283 const LogCB& log_cb) 272 const LogCB& log_cb)
284 : type_(AUDIO), 273 : type_(AUDIO), state_(RETURNING_DATA_FOR_READS) {
285 state_(RETURNING_DATA_FOR_READS) {
286 stream_.reset(new SourceBufferStream(audio_config, log_cb)); 274 stream_.reset(new SourceBufferStream(audio_config, log_cb));
287 } 275 }
288 276
289 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config, 277 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config,
290 const LogCB& log_cb) 278 const LogCB& log_cb)
291 : type_(VIDEO), 279 : type_(VIDEO), state_(RETURNING_DATA_FOR_READS) {
292 state_(RETURNING_DATA_FOR_READS) {
293 stream_.reset(new SourceBufferStream(video_config, log_cb)); 280 stream_.reset(new SourceBufferStream(video_config, log_cb));
294 } 281 }
295 282
296 void ChunkDemuxerStream::StartWaitingForSeek() { 283 void ChunkDemuxerStream::StartWaitingForSeek() {
297 DVLOG(1) << "ChunkDemuxerStream::StartWaitingForSeek()"; 284 DVLOG(1) << "ChunkDemuxerStream::StartWaitingForSeek()";
298 ReadCBQueue read_cbs; 285 ReadCBQueue read_cbs;
299 { 286 {
300 base::AutoLock auto_lock(lock_); 287 base::AutoLock auto_lock(lock_);
301 ChangeState_Locked(WAITING_FOR_SEEK); 288 ChangeState_Locked(WAITING_FOR_SEEK);
302 std::swap(read_cbs_, read_cbs); 289 std::swap(read_cbs_, read_cbs);
303 } 290 }
304 291
305 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 292 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
306 it->Run(kAborted, NULL); 293 it->Run(kAborted, NULL);
307 } 294 }
308 295
309 void ChunkDemuxerStream::Seek(TimeDelta time) { 296 void ChunkDemuxerStream::Seek(TimeDelta time) {
310 base::AutoLock auto_lock(lock_); 297 base::AutoLock auto_lock(lock_);
311 298
312 DCHECK(read_cbs_.empty()); 299 DCHECK(read_cbs_.empty());
313 300
314 // Ignore seek requests when canceled. 301 // Ignore seek requests when canceled.
315 if (state_ == CANCELED) 302 if (state_ == CANCELED) return;
316 return;
317 303
318 stream_->Seek(time); 304 stream_->Seek(time);
319 305
320 if (state_ == WAITING_FOR_SEEK) 306 if (state_ == WAITING_FOR_SEEK) ChangeState_Locked(RETURNING_DATA_FOR_READS);
321 ChangeState_Locked(RETURNING_DATA_FOR_READS);
322 } 307 }
323 308
324 void ChunkDemuxerStream::CancelPendingSeek() { 309 void ChunkDemuxerStream::CancelPendingSeek() {
325 DVLOG(1) << "ChunkDemuxerStream::CancelPendingSeek()"; 310 DVLOG(1) << "ChunkDemuxerStream::CancelPendingSeek()";
326 ReadCBQueue read_cbs; 311 ReadCBQueue read_cbs;
327 { 312 {
328 base::AutoLock auto_lock(lock_); 313 base::AutoLock auto_lock(lock_);
329 ChangeState_Locked(CANCELED); 314 ChangeState_Locked(CANCELED);
330 std::swap(read_cbs_, read_cbs); 315 std::swap(read_cbs_, read_cbs);
331 } 316 }
332 317
333 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 318 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
334 it->Run(kAborted, NULL); 319 it->Run(kAborted, NULL);
335 } 320 }
336 321
337 bool ChunkDemuxerStream::IsSeekPending() const { 322 bool ChunkDemuxerStream::IsSeekPending() const {
338 base::AutoLock auto_lock(lock_); 323 base::AutoLock auto_lock(lock_);
339 return stream_->IsSeekPending(); 324 return stream_->IsSeekPending();
340 } 325 }
341 326
342 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) { 327 void ChunkDemuxerStream::OnNewMediaSegment(TimeDelta start_timestamp) {
343 base::AutoLock auto_lock(lock_); 328 base::AutoLock auto_lock(lock_);
344 stream_->OnNewMediaSegment(start_timestamp); 329 stream_->OnNewMediaSegment(start_timestamp);
345 } 330 }
346 331
347 bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) { 332 bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {
348 if (buffers.empty()) 333 if (buffers.empty()) return false;
349 return false;
350 334
351 ClosureQueue closures; 335 ClosureQueue closures;
352 { 336 {
353 base::AutoLock auto_lock(lock_); 337 base::AutoLock auto_lock(lock_);
354 DCHECK_NE(state_, SHUTDOWN); 338 DCHECK_NE(state_, SHUTDOWN);
355 if (!stream_->Append(buffers)) { 339 if (!stream_->Append(buffers)) {
356 DVLOG(1) << "ChunkDemuxerStream::Append() : stream append failed"; 340 DVLOG(1) << "ChunkDemuxerStream::Append() : stream append failed";
357 return false; 341 return false;
358 } 342 }
359 CreateReadDoneClosures_Locked(&closures); 343 CreateReadDoneClosures_Locked(&closures);
360 } 344 }
361 345
362 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it) 346 for (ClosureQueue::iterator it = closures.begin(); it != closures.end(); ++it)
363 it->Run(); 347 it->Run();
364 348
365 return true; 349 return true;
366 } 350 }
367 351
368 void ChunkDemuxerStream::OnSetDuration(base::TimeDelta duration) { 352 void ChunkDemuxerStream::Onset_duration(base::TimeDelta duration) {
369 base::AutoLock auto_lock(lock_); 353 base::AutoLock auto_lock(lock_);
370 stream_->OnSetDuration(duration); 354 stream_->OnSetDuration(duration);
371 } 355 }
372 356
373 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( 357 Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
374 base::TimeDelta duration) const { 358 base::TimeDelta duration) const {
375 base::AutoLock auto_lock(lock_); 359 base::AutoLock auto_lock(lock_);
376 Ranges<TimeDelta> range = stream_->GetBufferedTime(); 360 Ranges<TimeDelta> range = stream_->GetBufferedTime();
377 361
378 if (range.size() == 0u) 362 if (range.size() == 0u) return range;
379 return range;
380 363
381 // Clamp the end of the stream's buffered ranges to fit within the duration. 364 // Clamp the end of the stream's buffered ranges to fit within the duration.
382 // This can be done by intersecting the stream's range with the valid time 365 // This can be done by intersecting the stream's range with the valid time
383 // range. 366 // range.
384 Ranges<TimeDelta> valid_time_range; 367 Ranges<TimeDelta> valid_time_range;
385 valid_time_range.Add(range.start(0), duration); 368 valid_time_range.Add(range.start(0), duration);
386 return range.IntersectionWith(valid_time_range); 369 return range.IntersectionWith(valid_time_range);
387 } 370 }
388 371
389 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 372 bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 ReadCBQueue read_cbs; 404 ReadCBQueue read_cbs;
422 { 405 {
423 base::AutoLock auto_lock(lock_); 406 base::AutoLock auto_lock(lock_);
424 ChangeState_Locked(SHUTDOWN); 407 ChangeState_Locked(SHUTDOWN);
425 std::swap(read_cbs_, read_cbs); 408 std::swap(read_cbs_, read_cbs);
426 } 409 }
427 410
428 // Pass end of stream buffers to all callbacks to signal that no more data 411 // Pass end of stream buffers to all callbacks to signal that no more data
429 // will be sent. 412 // will be sent.
430 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) 413 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it)
431 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer()); 414 it->Run(DemuxerStream::kOk, StreamParserBuffer::create_eos_buffer());
432 } 415 }
433 416
434 // Helper function that makes sure |read_cb| runs on |message_loop_proxy|. 417 // Helper function that makes sure |read_cb| runs on |message_loop_proxy|.
435 static void RunOnMessageLoop( 418 static void RunOnMessageLoop(
436 const DemuxerStream::ReadCB& read_cb, 419 const DemuxerStream::ReadCB& read_cb,
437 const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, 420 const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
438 DemuxerStream::Status status, 421 DemuxerStream::Status status, const scoped_refptr<DecoderBuffer>& buffer) {
439 const scoped_refptr<DecoderBuffer>& buffer) {
440 if (!message_loop_proxy->BelongsToCurrentThread()) { 422 if (!message_loop_proxy->BelongsToCurrentThread()) {
441 message_loop_proxy->PostTask(FROM_HERE, base::Bind( 423 message_loop_proxy->PostTask(
442 &RunOnMessageLoop, read_cb, message_loop_proxy, status, buffer)); 424 FROM_HERE, base::Bind(&RunOnMessageLoop, read_cb, message_loop_proxy,
425 status, buffer));
443 return; 426 return;
444 } 427 }
445 428
446 read_cb.Run(status, buffer); 429 read_cb.Run(status, buffer);
447 } 430 }
448 431
449 // DemuxerStream methods. 432 // DemuxerStream methods.
450 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { 433 void ChunkDemuxerStream::Read(const ReadCB& read_cb) {
451 DemuxerStream::Status status = kOk; 434 DemuxerStream::Status status = kOk;
452 scoped_refptr<StreamParserBuffer> buffer; 435 scoped_refptr<StreamParserBuffer> buffer;
453 { 436 {
454 base::AutoLock auto_lock(lock_); 437 base::AutoLock auto_lock(lock_);
455 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) { 438 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) {
456 DeferRead_Locked(read_cb); 439 DeferRead_Locked(read_cb);
457 return; 440 return;
458 } 441 }
459 } 442 }
460 443
461 base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( 444 base::MessageLoopProxy::current()->PostTask(
462 read_cb, status, buffer)); 445 FROM_HERE, base::Bind(read_cb, status, buffer));
463 } 446 }
464 447
465 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } 448 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; }
466 449
467 void ChunkDemuxerStream::EnableBitstreamConverter() {} 450 void ChunkDemuxerStream::EnableBitstreamConverter() {}
468 451
469 AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() { 452 AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() {
470 CHECK_EQ(type_, AUDIO); 453 CHECK_EQ(type_, AUDIO);
471 base::AutoLock auto_lock(lock_); 454 base::AutoLock auto_lock(lock_);
472 return stream_->GetCurrentAudioDecoderConfig(); 455 return stream_->GetCurrentAudioDecoderConfig();
473 } 456 }
474 457
475 VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() { 458 VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() {
476 CHECK_EQ(type_, VIDEO); 459 CHECK_EQ(type_, VIDEO);
477 base::AutoLock auto_lock(lock_); 460 base::AutoLock auto_lock(lock_);
478 return stream_->GetCurrentVideoDecoderConfig(); 461 return stream_->GetCurrentVideoDecoderConfig();
479 } 462 }
480 463
481 void ChunkDemuxerStream::ChangeState_Locked(State state) { 464 void ChunkDemuxerStream::ChangeState_Locked(State state) {
482 lock_.AssertAcquired(); 465 lock_.AssertAcquired();
483 DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : " 466 DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : "
484 << "type " << type_ 467 << "type " << type_ << " - " << state_ << " -> " << state;
485 << " - " << state_ << " -> " << state;
486 state_ = state; 468 state_ = state;
487 } 469 }
488 470
489 ChunkDemuxerStream::~ChunkDemuxerStream() {} 471 ChunkDemuxerStream::~ChunkDemuxerStream() {}
490 472
491 void ChunkDemuxerStream::DeferRead_Locked(const ReadCB& read_cb) { 473 void ChunkDemuxerStream::DeferRead_Locked(const ReadCB& read_cb) {
492 lock_.AssertAcquired(); 474 lock_.AssertAcquired();
493 // Wrap & store |read_cb| so that it will 475 // Wrap & store |read_cb| so that it will
494 // get called on the current MessageLoop. 476 // get called on the current MessageLoop.
495 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb, 477 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb,
496 base::MessageLoopProxy::current())); 478 base::MessageLoopProxy::current()));
497 } 479 }
498 480
499 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { 481 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) {
500 lock_.AssertAcquired(); 482 lock_.AssertAcquired();
501 483
502 if (state_ != RETURNING_DATA_FOR_READS) 484 if (state_ != RETURNING_DATA_FOR_READS) return;
503 return;
504 485
505 DemuxerStream::Status status; 486 DemuxerStream::Status status;
506 scoped_refptr<StreamParserBuffer> buffer; 487 scoped_refptr<StreamParserBuffer> buffer;
507 while (!read_cbs_.empty()) { 488 while (!read_cbs_.empty()) {
508 if (!GetNextBuffer_Locked(&status, &buffer)) 489 if (!GetNextBuffer_Locked(&status, &buffer)) return;
509 return; 490 closures->push_back(base::Bind(read_cbs_.front(), status, buffer));
510 closures->push_back(base::Bind(read_cbs_.front(),
511 status, buffer));
512 read_cbs_.pop_front(); 491 read_cbs_.pop_front();
513 } 492 }
514 } 493 }
515 494
516 bool ChunkDemuxerStream::GetNextBuffer_Locked( 495 bool ChunkDemuxerStream::GetNextBuffer_Locked(
517 DemuxerStream::Status* status, 496 DemuxerStream::Status* status, scoped_refptr<StreamParserBuffer>* buffer) {
518 scoped_refptr<StreamParserBuffer>* buffer) {
519 lock_.AssertAcquired(); 497 lock_.AssertAcquired();
520 498
521 switch (state_) { 499 switch (state_) {
522 case RETURNING_DATA_FOR_READS: 500 case RETURNING_DATA_FOR_READS:
523 switch (stream_->GetNextBuffer(buffer)) { 501 switch (stream_->GetNextBuffer(buffer)) {
524 case SourceBufferStream::kSuccess: 502 case SourceBufferStream::kSuccess:
525 *status = DemuxerStream::kOk; 503 *status = DemuxerStream::kOk;
526 return true; 504 return true;
527 case SourceBufferStream::kNeedBuffer: 505 case SourceBufferStream::kNeedBuffer:
528 return false; 506 return false;
529 case SourceBufferStream::kEndOfStream: 507 case SourceBufferStream::kEndOfStream:
530 *status = DemuxerStream::kOk; 508 *status = DemuxerStream::kOk;
531 *buffer = StreamParserBuffer::CreateEOSBuffer(); 509 *buffer = StreamParserBuffer::create_eos_buffer();
532 return true; 510 return true;
533 case SourceBufferStream::kConfigChange: 511 case SourceBufferStream::kConfigChange:
534 DVLOG(2) << "Config change reported to ChunkDemuxerStream."; 512 DVLOG(2) << "Config change reported to ChunkDemuxerStream.";
535 *status = kConfigChanged; 513 *status = kConfigChanged;
536 *buffer = NULL; 514 *buffer = NULL;
537 return true; 515 return true;
538 } 516 }
539 break; 517 break;
540 case CANCELED: 518 case CANCELED:
541 case WAITING_FOR_SEEK: 519 case WAITING_FOR_SEEK:
542 // Null buffers should be returned in this state since we are waiting 520 // Null buffers should be returned in this state since we are waiting
543 // for a seek. Any buffers in the SourceBuffer should NOT be returned 521 // for a seek. Any buffers in the SourceBuffer should NOT be returned
544 // because they are associated with the seek. 522 // because they are associated with the seek.
545 DCHECK(read_cbs_.empty()); 523 DCHECK(read_cbs_.empty());
546 *status = DemuxerStream::kAborted; 524 *status = DemuxerStream::kAborted;
547 *buffer = NULL; 525 *buffer = NULL;
548 return true; 526 return true;
549 case SHUTDOWN: 527 case SHUTDOWN:
550 DCHECK(read_cbs_.empty()); 528 DCHECK(read_cbs_.empty());
551 *status = DemuxerStream::kOk; 529 *status = DemuxerStream::kOk;
552 *buffer = StreamParserBuffer::CreateEOSBuffer(); 530 *buffer = StreamParserBuffer::create_eos_buffer();
553 return true; 531 return true;
554 } 532 }
555 533
556 NOTREACHED(); 534 NOTREACHED();
557 return false; 535 return false;
558 } 536 }
559 537
560 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, 538 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb,
561 const NeedKeyCB& need_key_cb, 539 const NeedKeyCB& need_key_cb,
562 const AddTextTrackCB& add_text_track_cb, 540 const AddTextTrackCB& add_text_track_cb,
563 const LogCB& log_cb) 541 const LogCB& log_cb)
564 : state_(WAITING_FOR_INIT), 542 : state_(WAITING_FOR_INIT),
565 host_(NULL), 543 host_(NULL),
566 open_cb_(open_cb), 544 open_cb_(open_cb),
567 need_key_cb_(need_key_cb), 545 need_key_cb_(need_key_cb),
568 add_text_track_cb_(add_text_track_cb), 546 add_text_track_cb_(add_text_track_cb),
569 log_cb_(log_cb), 547 log_cb_(log_cb),
570 duration_(kNoTimestamp()), 548 duration_(kNoTimestamp()),
571 user_specified_duration_(-1) { 549 user_specified_duration_(-1) {
572 DCHECK(!open_cb_.is_null()); 550 DCHECK(!open_cb_.is_null());
573 DCHECK(!need_key_cb_.is_null()); 551 DCHECK(!need_key_cb_.is_null());
574 } 552 }
575 553
576 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { 554 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) {
577 DVLOG(1) << "Init()"; 555 DVLOG(1) << "Init()";
578 556
579 base::AutoLock auto_lock(lock_); 557 base::AutoLock auto_lock(lock_);
580 558
581 if (state_ == SHUTDOWN) { 559 if (state_ == SHUTDOWN) {
582 base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( 560 base::MessageLoopProxy::current()->PostTask(
583 cb, DEMUXER_ERROR_COULD_NOT_OPEN)); 561 FROM_HERE, base::Bind(cb, DEMUXER_ERROR_COULD_NOT_OPEN));
584 return; 562 return;
585 } 563 }
586 DCHECK_EQ(state_, WAITING_FOR_INIT); 564 DCHECK_EQ(state_, WAITING_FOR_INIT);
587 host_ = host; 565 host_ = host;
588 566
589 ChangeState_Locked(INITIALIZING); 567 ChangeState_Locked(INITIALIZING);
590 init_cb_ = cb; 568 init_cb_ = cb;
591 569
592 base::ResetAndReturn(&open_cb_).Run(); 570 base::ResetAndReturn(&open_cb_).Run();
593 } 571 }
594 572
595 void ChunkDemuxer::Stop(const base::Closure& callback) { 573 void ChunkDemuxer::Stop(const base::Closure& callback) {
596 DVLOG(1) << "Stop()"; 574 DVLOG(1) << "Stop()";
597 Shutdown(); 575 Shutdown();
598 callback.Run(); 576 callback.Run();
599 } 577 }
600 578
601 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) { 579 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) {
602 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; 580 DVLOG(1) << "Seek(" << time.InSecondsF() << ")";
603 DCHECK(time >= TimeDelta()); 581 DCHECK(time >= TimeDelta());
604 DCHECK(seek_cb_.is_null()); 582 DCHECK(seek_cb_.is_null());
605 583
606 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; 584 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE;
607 { 585 {
608 base::AutoLock auto_lock(lock_); 586 base::AutoLock auto_lock(lock_);
609 587
610 if (state_ == INITIALIZED || state_ == ENDED) { 588 if (state_ == INITIALIZED || state_ == ENDED) {
611 if (audio_) 589 if (audio_) audio_->Seek(time);
612 audio_->Seek(time);
613 590
614 if (video_) 591 if (video_) video_->Seek(time);
615 video_->Seek(time);
616 592
617 if (IsSeekPending_Locked()) { 593 if (IsSeekPending_Locked()) {
618 DVLOG(1) << "Seek() : waiting for more data to arrive."; 594 DVLOG(1) << "Seek() : waiting for more data to arrive.";
619 seek_cb_ = cb; 595 seek_cb_ = cb;
620 return; 596 return;
621 } 597 }
622 598
623 status = PIPELINE_OK; 599 status = PIPELINE_OK;
624 } 600 }
625 } 601 }
626 602
627 cb.Run(status); 603 cb.Run(status);
628 } 604 }
629 605
630 void ChunkDemuxer::OnAudioRendererDisabled() { 606 void ChunkDemuxer::OnAudioRendererDisabled() {
631 base::AutoLock auto_lock(lock_); 607 base::AutoLock auto_lock(lock_);
632 audio_->Shutdown(); 608 audio_->Shutdown();
633 disabled_audio_ = audio_.Pass(); 609 disabled_audio_ = audio_.Pass();
634 } 610 }
635 611
636 // Demuxer implementation. 612 // Demuxer implementation.
637 DemuxerStream* ChunkDemuxer::GetStream(DemuxerStream::Type type) { 613 DemuxerStream* ChunkDemuxer::GetStream(DemuxerStream::Type type) {
638 base::AutoLock auto_lock(lock_); 614 base::AutoLock auto_lock(lock_);
639 if (type == DemuxerStream::VIDEO) 615 if (type == DemuxerStream::VIDEO) return video_.get();
640 return video_.get();
641 616
642 if (type == DemuxerStream::AUDIO) 617 if (type == DemuxerStream::AUDIO) return audio_.get();
643 return audio_.get();
644 618
645 return NULL; 619 return NULL;
646 } 620 }
647 621
648 TimeDelta ChunkDemuxer::GetStartTime() const { 622 TimeDelta ChunkDemuxer::GetStartTime() const { return TimeDelta(); }
649 return TimeDelta();
650 }
651 623
652 void ChunkDemuxer::StartWaitingForSeek() { 624 void ChunkDemuxer::StartWaitingForSeek() {
653 DVLOG(1) << "StartWaitingForSeek()"; 625 DVLOG(1) << "StartWaitingForSeek()";
654 base::AutoLock auto_lock(lock_); 626 base::AutoLock auto_lock(lock_);
655 DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN); 627 DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN);
656 628
657 if (state_ == SHUTDOWN) 629 if (state_ == SHUTDOWN) return;
658 return;
659 630
660 if (audio_) 631 if (audio_) audio_->StartWaitingForSeek();
661 audio_->StartWaitingForSeek();
662 632
663 if (video_) 633 if (video_) video_->StartWaitingForSeek();
664 video_->StartWaitingForSeek();
665 } 634 }
666 635
667 void ChunkDemuxer::CancelPendingSeek() { 636 void ChunkDemuxer::CancelPendingSeek() {
668 PipelineStatusCB cb; 637 PipelineStatusCB cb;
669 { 638 {
670 base::AutoLock auto_lock(lock_); 639 base::AutoLock auto_lock(lock_);
671 if (IsSeekPending_Locked() && !seek_cb_.is_null()) { 640 if (IsSeekPending_Locked() && !seek_cb_.is_null()) {
672 std::swap(cb, seek_cb_); 641 std::swap(cb, seek_cb_);
673 } 642 }
674 if (audio_) 643 if (audio_) audio_->CancelPendingSeek();
675 audio_->CancelPendingSeek();
676 644
677 if (video_) 645 if (video_) video_->CancelPendingSeek();
678 video_->CancelPendingSeek();
679 } 646 }
680 647
681 if (!cb.is_null()) 648 if (!cb.is_null()) cb.Run(PIPELINE_OK);
682 cb.Run(PIPELINE_OK);
683 } 649 }
684 650
685 ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, 651 ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
686 const std::string& type, 652 const std::string& type,
687 std::vector<std::string>& codecs) { 653 std::vector<std::string>& codecs) {
688 DCHECK_GT(codecs.size(), 0u); 654 DCHECK_GT(codecs.size(), 0u);
689 base::AutoLock auto_lock(lock_); 655 base::AutoLock auto_lock(lock_);
690 656
691 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id)) 657 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id))
692 return kReachedIdLimit; 658 return kReachedIdLimit;
693 659
694 bool has_audio = false; 660 bool has_audio = false;
695 bool has_video = false; 661 bool has_video = false;
696 scoped_ptr<media::StreamParser> stream_parser( 662 scoped_ptr<media::StreamParser> stream_parser(StreamParserFactory::Create(
697 StreamParserFactory::Create(type, codecs, log_cb_, 663 type, codecs, log_cb_, &has_audio, &has_video));
698 &has_audio, &has_video));
699 664
700 if (!stream_parser) 665 if (!stream_parser) return ChunkDemuxer::kNotSupported;
701 return ChunkDemuxer::kNotSupported;
702 666
703 if ((has_audio && !source_id_audio_.empty()) || 667 if ((has_audio && !source_id_audio_.empty()) ||
704 (has_video && !source_id_video_.empty())) 668 (has_video && !source_id_video_.empty()))
705 return kReachedIdLimit; 669 return kReachedIdLimit;
706 670
707 StreamParser::NewBuffersCB audio_cb; 671 StreamParser::NewBuffersCB audio_cb;
708 StreamParser::NewBuffersCB video_cb; 672 StreamParser::NewBuffersCB video_cb;
709 673
710 if (has_audio) { 674 if (has_audio) {
711 source_id_audio_ = id; 675 source_id_audio_ = id;
712 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, 676 audio_cb =
713 base::Unretained(this)); 677 base::Bind(&ChunkDemuxer::OnAudioBuffers, base::Unretained(this));
714 } 678 }
715 679
716 if (has_video) { 680 if (has_video) {
717 source_id_video_ = id; 681 source_id_video_ = id;
718 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers, 682 video_cb =
719 base::Unretained(this)); 683 base::Bind(&ChunkDemuxer::OnVideoBuffers, base::Unretained(this));
720 } 684 }
721 685
722 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass())); 686 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass()));
723 source_state->Init( 687 source_state->Init(
724 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), 688 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)),
725 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), 689 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), has_audio,
726 has_audio, has_video), 690 has_video),
727 audio_cb, 691 audio_cb, video_cb,
728 video_cb,
729 base::Bind(&ChunkDemuxer::OnTextBuffers, base::Unretained(this)), 692 base::Bind(&ChunkDemuxer::OnTextBuffers, base::Unretained(this)),
730 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), 693 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)),
731 add_text_track_cb_, 694 add_text_track_cb_,
732 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), 695 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id),
733 log_cb_); 696 log_cb_);
734 697
735 source_state_map_[id] = source_state.release(); 698 source_state_map_[id] = source_state.release();
736 return kOk; 699 return kOk;
737 } 700 }
738 701
739 void ChunkDemuxer::RemoveId(const std::string& id) { 702 void ChunkDemuxer::RemoveId(const std::string& id) {
740 base::AutoLock auto_lock(lock_); 703 base::AutoLock auto_lock(lock_);
741 CHECK(IsValidId(id)); 704 CHECK(IsValidId(id));
742 705
743 delete source_state_map_[id]; 706 delete source_state_map_[id];
744 source_state_map_.erase(id); 707 source_state_map_.erase(id);
745 708
746 if (source_id_audio_ == id) { 709 if (source_id_audio_ == id) {
747 if (audio_) 710 if (audio_) audio_->Shutdown();
748 audio_->Shutdown();
749 source_id_audio_.clear(); 711 source_id_audio_.clear();
750 } 712 }
751 713
752 if (source_id_video_ == id) { 714 if (source_id_video_ == id) {
753 if (video_) 715 if (video_) video_->Shutdown();
754 video_->Shutdown();
755 source_id_video_.clear(); 716 source_id_video_.clear();
756 } 717 }
757 } 718 }
758 719
759 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { 720 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const {
760 base::AutoLock auto_lock(lock_); 721 base::AutoLock auto_lock(lock_);
761 DCHECK(!id.empty()); 722 DCHECK(!id.empty());
762 DCHECK(IsValidId(id)); 723 DCHECK(IsValidId(id));
763 DCHECK(id == source_id_audio_ || id == source_id_video_); 724 DCHECK(id == source_id_audio_ || id == source_id_video_);
764 725
765 if (id == source_id_audio_ && id != source_id_video_) { 726 if (id == source_id_audio_ && id != source_id_video_) {
766 // Only include ranges that have been buffered in |audio_| 727 // Only include ranges that have been buffered in |audio_|
767 return audio_ ? audio_->GetBufferedRanges(duration_) : Ranges<TimeDelta>(); 728 return audio_ ? audio_->GetBufferedRanges(duration_) : Ranges<TimeDelta>();
768 } 729 }
769 730
770 if (id != source_id_audio_ && id == source_id_video_) { 731 if (id != source_id_audio_ && id == source_id_video_) {
771 // Only include ranges that have been buffered in |video_| 732 // Only include ranges that have been buffered in |video_|
772 return video_ ? video_->GetBufferedRanges(duration_) : Ranges<TimeDelta>(); 733 return video_ ? video_->GetBufferedRanges(duration_) : Ranges<TimeDelta>();
773 } 734 }
774 735
775 return ComputeIntersection(); 736 return ComputeIntersection();
776 } 737 }
777 738
778 Ranges<TimeDelta> ChunkDemuxer::ComputeIntersection() const { 739 Ranges<TimeDelta> ChunkDemuxer::ComputeIntersection() const {
779 lock_.AssertAcquired(); 740 lock_.AssertAcquired();
780 741
781 if (!audio_ || !video_) 742 if (!audio_ || !video_) return Ranges<TimeDelta>();
782 return Ranges<TimeDelta>();
783 743
784 // Include ranges that have been buffered in both |audio_| and |video_|. 744 // Include ranges that have been buffered in both |audio_| and |video_|.
785 Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(duration_); 745 Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(duration_);
786 Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(duration_); 746 Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(duration_);
787 Ranges<TimeDelta> result = audio_ranges.IntersectionWith(video_ranges); 747 Ranges<TimeDelta> result = audio_ranges.IntersectionWith(video_ranges);
788 748
789 if (state_ == ENDED && result.size() > 0) { 749 if (state_ == ENDED && result.size() > 0) {
790 // If appending has ended, extend the last intersection range to include the 750 // If appending has ended, extend the last intersection range to include the
791 // max end time of the last audio/video range. This allows the buffered 751 // max end time of the last audio/video range. This allows the buffered
792 // information to match the actual time range that will get played out if 752 // information to match the actual time range that will get played out if
793 // the streams have slightly different lengths. 753 // the streams have slightly different lengths.
794 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1); 754 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1);
795 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1); 755 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1);
796 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1); 756 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1);
797 TimeDelta video_end = video_ranges.end(video_ranges.size() - 1); 757 TimeDelta video_end = video_ranges.end(video_ranges.size() - 1);
798 758
799 // Verify the last audio range overlaps with the last video range. 759 // Verify the last audio range overlaps with the last video range.
800 // This is enforced by the logic that controls the transition to ENDED. 760 // This is enforced by the logic that controls the transition to ENDED.
801 DCHECK((audio_start <= video_start && video_start <= audio_end) || 761 DCHECK((audio_start <= video_start && video_start <= audio_end) ||
802 (video_start <= audio_start && audio_start <= video_end)); 762 (video_start <= audio_start && audio_start <= video_end));
803 result.Add(result.end(result.size()-1), std::max(audio_end, video_end)); 763 result.Add(result.end(result.size() - 1), std::max(audio_end, video_end));
804 } 764 }
805 765
806 return result; 766 return result;
807 } 767 }
808 768
809 void ChunkDemuxer::AppendData(const std::string& id, 769 void ChunkDemuxer::AppendData(const std::string& id, const uint8* data,
810 const uint8* data,
811 size_t length) { 770 size_t length) {
812 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 771 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
813 772
814 DCHECK(!id.empty()); 773 DCHECK(!id.empty());
815 774
816 Ranges<TimeDelta> ranges; 775 Ranges<TimeDelta> ranges;
817 776
818 PipelineStatusCB cb; 777 PipelineStatusCB cb;
819 { 778 {
820 base::AutoLock auto_lock(lock_); 779 base::AutoLock auto_lock(lock_);
821 780
822 // Capture if the SourceBuffer has a pending seek before we start parsing. 781 // Capture if the SourceBuffer has a pending seek before we start parsing.
823 bool old_seek_pending = IsSeekPending_Locked(); 782 bool old_seek_pending = IsSeekPending_Locked();
824 783
825 if (state_ == ENDED) { 784 if (state_ == ENDED) {
826 ChangeState_Locked(INITIALIZED); 785 ChangeState_Locked(INITIALIZED);
827 786
828 if (audio_) 787 if (audio_) audio_->CancelEndOfStream();
829 audio_->CancelEndOfStream();
830 788
831 if (video_) 789 if (video_) video_->CancelEndOfStream();
832 video_->CancelEndOfStream();
833 } 790 }
834 791
835 if (length == 0u) 792 if (length == 0u) return;
836 return;
837 793
838 DCHECK(data); 794 DCHECK(data);
839 795
840 switch (state_) { 796 switch (state_) {
841 case INITIALIZING: 797 case INITIALIZING:
842 DCHECK(IsValidId(id)); 798 DCHECK(IsValidId(id));
843 if (!source_state_map_[id]->Append(data, length)) { 799 if (!source_state_map_[id]->Append(data, length)) {
844 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 800 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
845 return; 801 return;
846 } 802 }
(...skipping 23 matching lines...) Expand all
870 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) { 826 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) {
871 std::swap(cb, seek_cb_); 827 std::swap(cb, seek_cb_);
872 } 828 }
873 829
874 ranges = GetBufferedRanges(); 830 ranges = GetBufferedRanges();
875 } 831 }
876 832
877 for (size_t i = 0; i < ranges.size(); ++i) 833 for (size_t i = 0; i < ranges.size(); ++i)
878 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i)); 834 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i));
879 835
880 if (!cb.is_null()) 836 if (!cb.is_null()) cb.Run(PIPELINE_OK);
881 cb.Run(PIPELINE_OK);
882 } 837 }
883 838
884 void ChunkDemuxer::Abort(const std::string& id) { 839 void ChunkDemuxer::Abort(const std::string& id) {
885 DVLOG(1) << "Abort(" << id << ")"; 840 DVLOG(1) << "Abort(" << id << ")";
886 base::AutoLock auto_lock(lock_); 841 base::AutoLock auto_lock(lock_);
887 DCHECK(!id.empty()); 842 DCHECK(!id.empty());
888 CHECK(IsValidId(id)); 843 CHECK(IsValidId(id));
889 source_state_map_[id]->Abort(); 844 source_state_map_[id]->Abort();
890 } 845 }
891 846
892 double ChunkDemuxer::GetDuration() { 847 double ChunkDemuxer::GetDuration() {
893 base::AutoLock auto_lock(lock_); 848 base::AutoLock auto_lock(lock_);
894 return GetDuration_Locked(); 849 return GetDuration_Locked();
895 } 850 }
896 851
897 double ChunkDemuxer::GetDuration_Locked() { 852 double ChunkDemuxer::GetDuration_Locked() {
898 lock_.AssertAcquired(); 853 lock_.AssertAcquired();
899 if (duration_ == kNoTimestamp()) 854 if (duration_ == kNoTimestamp())
900 return std::numeric_limits<double>::quiet_NaN(); 855 return std::numeric_limits<double>::quiet_NaN();
901 856
902 // Return positive infinity if the resource is unbounded. 857 // Return positive infinity if the resource is unbounded.
903 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom- media-duration 858 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom- media-duration
904 if (duration_ == kInfiniteDuration()) 859 if (duration_ == kInfiniteDuration())
905 return std::numeric_limits<double>::infinity(); 860 return std::numeric_limits<double>::infinity();
906 861
907 if (user_specified_duration_ >= 0) 862 if (user_specified_duration_ >= 0) return user_specified_duration_;
908 return user_specified_duration_;
909 863
910 return duration_.InSecondsF(); 864 return duration_.InSecondsF();
911 } 865 }
912 866
913 void ChunkDemuxer::SetDuration(double duration) { 867 void ChunkDemuxer::SetDuration(double duration) {
914 base::AutoLock auto_lock(lock_); 868 base::AutoLock auto_lock(lock_);
915 DVLOG(1) << "SetDuration(" << duration << ")"; 869 DVLOG(1) << "set_duration(" << duration << ")";
916 DCHECK_GE(duration, 0); 870 DCHECK_GE(duration, 0);
917 871
918 if (duration == GetDuration_Locked()) 872 if (duration == GetDuration_Locked()) return;
919 return;
920 873
921 // Compute & bounds check the TimeDelta representation of duration. 874 // Compute & bounds check the TimeDelta representation of duration.
922 // This can be different if the value of |duration| doesn't fit the range or 875 // This can be different if the value of |duration| doesn't fit the range or
923 // precision of base::TimeDelta. 876 // precision of base::TimeDelta.
924 base::TimeDelta min_duration = base::TimeDelta::FromInternalValue(1); 877 base::TimeDelta min_duration = base::TimeDelta::FromInternalValue(1);
925 base::TimeDelta max_duration = 878 base::TimeDelta max_duration =
926 base::TimeDelta::FromInternalValue(kint64max - 1); 879 base::TimeDelta::FromInternalValue(kint64max - 1);
927 double min_duration_in_seconds = min_duration.InSecondsF(); 880 double min_duration_in_seconds = min_duration.InSecondsF();
928 double max_duration_in_seconds = max_duration.InSecondsF(); 881 double max_duration_in_seconds = max_duration.InSecondsF();
929 882
930 base::TimeDelta duration_td; 883 base::TimeDelta duration_td;
931 if (duration == std::numeric_limits<double>::infinity()) { 884 if (duration == std::numeric_limits<double>::infinity()) {
932 duration_td = media::kInfiniteDuration(); 885 duration_td = media::kInfiniteDuration();
933 } else if (duration < min_duration_in_seconds) { 886 } else if (duration < min_duration_in_seconds) {
934 duration_td = min_duration; 887 duration_td = min_duration;
935 } else if (duration > max_duration_in_seconds) { 888 } else if (duration > max_duration_in_seconds) {
936 duration_td = max_duration; 889 duration_td = max_duration;
937 } else { 890 } else {
938 duration_td = base::TimeDelta::FromMicroseconds( 891 duration_td = base::TimeDelta::FromMicroseconds(
939 duration * base::Time::kMicrosecondsPerSecond); 892 duration * base::Time::kMicrosecondsPerSecond);
940 } 893 }
941 894
942 DCHECK(duration_td > base::TimeDelta()); 895 DCHECK(duration_td > base::TimeDelta());
943 896
944 user_specified_duration_ = duration; 897 user_specified_duration_ = duration;
945 duration_ = duration_td; 898 duration_ = duration_td;
946 host_->SetDuration(duration_); 899 host_->SetDuration(duration_);
947 900
948 if (audio_) 901 if (audio_) audio_->Onset_duration(duration_);
949 audio_->OnSetDuration(duration_);
950 902
951 if (video_) 903 if (video_) video_->Onset_duration(duration_);
952 video_->OnSetDuration(duration_);
953 } 904 }
954 905
955 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { 906 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) {
956 base::AutoLock auto_lock(lock_); 907 base::AutoLock auto_lock(lock_);
957 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; 908 DVLOG(1) << "set_timestampOffset(" << id << ", " << offset.InSecondsF()
909 << ")";
958 CHECK(IsValidId(id)); 910 CHECK(IsValidId(id));
959 911
960 return source_state_map_[id]->SetTimestampOffset(offset); 912 return source_state_map_[id]->set_timestampOffset(offset);
961 } 913 }
962 914
963 void ChunkDemuxer::EndOfStream(PipelineStatus status) { 915 void ChunkDemuxer::EndOfStream(PipelineStatus status) {
964 DVLOG(1) << "EndOfStream(" << status << ")"; 916 DVLOG(1) << "EndOfStream(" << status << ")";
965 PipelineStatusCB cb; 917 PipelineStatusCB cb;
966 { 918 {
967 base::AutoLock auto_lock(lock_); 919 base::AutoLock auto_lock(lock_);
968 DCHECK_NE(state_, WAITING_FOR_INIT); 920 DCHECK_NE(state_, WAITING_FOR_INIT);
969 DCHECK_NE(state_, ENDED); 921 DCHECK_NE(state_, ENDED);
970 922
971 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) 923 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) return;
972 return;
973 924
974 if (state_ == INITIALIZING) { 925 if (state_ == INITIALIZING) {
975 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 926 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
976 return; 927 return;
977 } 928 }
978 929
979 bool old_seek_pending = IsSeekPending_Locked(); 930 bool old_seek_pending = IsSeekPending_Locked();
980 if (audio_) 931 if (audio_) audio_->EndOfStream();
981 audio_->EndOfStream();
982 932
983 if (video_) 933 if (video_) video_->EndOfStream();
984 video_->EndOfStream();
985 934
986 // Give a chance to resume the pending seek process. 935 // Give a chance to resume the pending seek process.
987 if (status != PIPELINE_OK) { 936 if (status != PIPELINE_OK) {
988 ReportError_Locked(status); 937 ReportError_Locked(status);
989 return; 938 return;
990 } 939 }
991 940
992 ChangeState_Locked(ENDED); 941 ChangeState_Locked(ENDED);
993 DecreaseDurationIfNecessary(); 942 DecreaseDurationIfNecessary();
994 943
995 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) 944 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null())
996 std::swap(cb, seek_cb_); 945 std::swap(cb, seek_cb_);
997 } 946 }
998 947
999 if (!cb.is_null()) 948 if (!cb.is_null()) cb.Run(PIPELINE_OK);
1000 cb.Run(PIPELINE_OK);
1001 } 949 }
1002 950
1003 void ChunkDemuxer::Shutdown() { 951 void ChunkDemuxer::Shutdown() {
1004 DVLOG(1) << "Shutdown()"; 952 DVLOG(1) << "Shutdown()";
1005 PipelineStatusCB cb; 953 PipelineStatusCB cb;
1006 { 954 {
1007 base::AutoLock auto_lock(lock_); 955 base::AutoLock auto_lock(lock_);
1008 956
1009 if (state_ == SHUTDOWN) 957 if (state_ == SHUTDOWN) return;
1010 return;
1011 958
1012 std::swap(cb, seek_cb_); 959 std::swap(cb, seek_cb_);
1013 960
1014 if (audio_) 961 if (audio_) audio_->Shutdown();
1015 audio_->Shutdown();
1016 962
1017 if (video_) 963 if (video_) video_->Shutdown();
1018 video_->Shutdown();
1019 964
1020 ChangeState_Locked(SHUTDOWN); 965 ChangeState_Locked(SHUTDOWN);
1021 } 966 }
1022 967
1023 if (!cb.is_null()) 968 if (!cb.is_null()) cb.Run(PIPELINE_ERROR_ABORT);
1024 cb.Run(PIPELINE_ERROR_ABORT);
1025 } 969 }
1026 970
1027 void ChunkDemuxer::ChangeState_Locked(State new_state) { 971 void ChunkDemuxer::ChangeState_Locked(State new_state) {
1028 lock_.AssertAcquired(); 972 lock_.AssertAcquired();
1029 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " 973 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " << state_ << " -> "
1030 << state_ << " -> " << new_state; 974 << new_state;
1031 state_ = new_state; 975 state_ = new_state;
1032 } 976 }
1033 977
1034 ChunkDemuxer::~ChunkDemuxer() { 978 ChunkDemuxer::~ChunkDemuxer() {
1035 DCHECK_NE(state_, INITIALIZED); 979 DCHECK_NE(state_, INITIALIZED);
1036 for (SourceStateMap::iterator it = source_state_map_.begin(); 980 for (SourceStateMap::iterator it = source_state_map_.begin();
1037 it != source_state_map_.end(); ++it) { 981 it != source_state_map_.end(); ++it) {
1038 delete it->second; 982 delete it->second;
1039 } 983 }
1040 source_state_map_.clear(); 984 source_state_map_.clear();
1041 } 985 }
1042 986
1043 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { 987 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
1044 DVLOG(1) << "ReportError_Locked(" << error << ")"; 988 DVLOG(1) << "ReportError_Locked(" << error << ")";
1045 lock_.AssertAcquired(); 989 lock_.AssertAcquired();
1046 DCHECK_NE(error, PIPELINE_OK); 990 DCHECK_NE(error, PIPELINE_OK);
1047 991
1048 ChangeState_Locked(PARSE_ERROR); 992 ChangeState_Locked(PARSE_ERROR);
1049 993
1050 PipelineStatusCB cb; 994 PipelineStatusCB cb;
1051 995
1052 if (!init_cb_.is_null()) { 996 if (!init_cb_.is_null()) {
1053 std::swap(cb, init_cb_); 997 std::swap(cb, init_cb_);
1054 } else { 998 } else {
1055 if (!seek_cb_.is_null()) 999 if (!seek_cb_.is_null()) std::swap(cb, seek_cb_);
1056 std::swap(cb, seek_cb_);
1057 1000
1058 if (audio_) 1001 if (audio_) audio_->Shutdown();
1059 audio_->Shutdown();
1060 1002
1061 if (video_) 1003 if (video_) video_->Shutdown();
1062 video_->Shutdown();
1063 } 1004 }
1064 1005
1065 if (!cb.is_null()) { 1006 if (!cb.is_null()) {
1066 base::AutoUnlock auto_unlock(lock_); 1007 base::AutoUnlock auto_unlock(lock_);
1067 cb.Run(error); 1008 cb.Run(error);
1068 return; 1009 return;
1069 } 1010 }
1070 1011
1071 base::AutoUnlock auto_unlock(lock_); 1012 base::AutoUnlock auto_unlock(lock_);
1072 host_->OnDemuxerError(error); 1013 host_->OnDemuxerError(error);
1073 } 1014 }
1074 1015
1075 bool ChunkDemuxer::IsSeekPending_Locked() const { 1016 bool ChunkDemuxer::IsSeekPending_Locked() const {
1076 lock_.AssertAcquired(); 1017 lock_.AssertAcquired();
1077 bool seek_pending = false; 1018 bool seek_pending = false;
1078 1019
1079 if (audio_) 1020 if (audio_) seek_pending = audio_->IsSeekPending();
1080 seek_pending = audio_->IsSeekPending();
1081 1021
1082 if (!seek_pending && video_) 1022 if (!seek_pending && video_) seek_pending = video_->IsSeekPending();
1083 seek_pending = video_->IsSeekPending();
1084 1023
1085 return seek_pending; 1024 return seek_pending;
1086 } 1025 }
1087 1026
1088 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) { 1027 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
1089 DVLOG(1) << "OnSourceInitDone(" << success << ", " 1028 DVLOG(1) << "OnSourceInitDone(" << success << ", " << duration.InSecondsF()
1090 << duration.InSecondsF() << ")"; 1029 << ")";
1091 lock_.AssertAcquired(); 1030 lock_.AssertAcquired();
1092 DCHECK_EQ(state_, INITIALIZING); 1031 DCHECK_EQ(state_, INITIALIZING);
1093 if (!success || (!audio_ && !video_)) { 1032 if (!success || (!audio_ && !video_)) {
1094 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1033 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1095 return; 1034 return;
1096 } 1035 }
1097 1036
1098 if (duration != base::TimeDelta() && duration_ == kNoTimestamp()) 1037 if (duration != base::TimeDelta() && duration_ == kNoTimestamp())
1099 UpdateDuration(duration); 1038 UpdateDuration(duration);
1100 1039
1101 // Wait until all streams have initialized. 1040 // Wait until all streams have initialized.
1102 if ((!source_id_audio_.empty() && !audio_) || 1041 if ((!source_id_audio_.empty() && !audio_) ||
1103 (!source_id_video_.empty() && !video_)) 1042 (!source_id_video_.empty() && !video_))
1104 return; 1043 return;
1105 1044
1106 if (audio_) 1045 if (audio_) audio_->Seek(TimeDelta());
1107 audio_->Seek(TimeDelta());
1108 1046
1109 if (video_) 1047 if (video_) video_->Seek(TimeDelta());
1110 video_->Seek(TimeDelta());
1111 1048
1112 if (duration_ == kNoTimestamp()) 1049 if (duration_ == kNoTimestamp()) duration_ = kInfiniteDuration();
1113 duration_ = kInfiniteDuration();
1114 1050
1115 // The demuxer is now initialized after the |start_timestamp_| was set. 1051 // The demuxer is now initialized after the |start_timestamp_| was set.
1116 ChangeState_Locked(INITIALIZED); 1052 ChangeState_Locked(INITIALIZED);
1117 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 1053 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
1118 } 1054 }
1119 1055
1120 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, 1056 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video,
1121 const AudioDecoderConfig& audio_config, 1057 const AudioDecoderConfig& audio_config,
1122 const VideoDecoderConfig& video_config) { 1058 const VideoDecoderConfig& video_config) {
1123 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video 1059 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video << ", "
1124 << ", " << audio_config.IsValidConfig() 1060 << audio_config.IsValidConfig() << ", "
1125 << ", " << video_config.IsValidConfig() << ")"; 1061 << video_config.IsValidConfig() << ")";
1126 lock_.AssertAcquired(); 1062 lock_.AssertAcquired();
1127 1063
1128 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) { 1064 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) {
1129 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!"; 1065 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!";
1130 return false; 1066 return false;
1131 } 1067 }
1132 1068
1133 // Signal an error if we get configuration info for stream types that weren't 1069 // Signal an error if we get configuration info for stream types that weren't
1134 // specified in AddId() or more configs after a stream is initialized. 1070 // specified in AddId() or more configs after a stream is initialized.
1135 // Only allow a single audio config for now. 1071 // Only allow a single audio config for now.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 } 1108 }
1173 1109
1174 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); 1110 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed");
1175 return success; 1111 return success;
1176 } 1112 }
1177 1113
1178 bool ChunkDemuxer::OnAudioBuffers(const StreamParser::BufferQueue& buffers) { 1114 bool ChunkDemuxer::OnAudioBuffers(const StreamParser::BufferQueue& buffers) {
1179 lock_.AssertAcquired(); 1115 lock_.AssertAcquired();
1180 DCHECK_NE(state_, SHUTDOWN); 1116 DCHECK_NE(state_, SHUTDOWN);
1181 1117
1182 if (!audio_) 1118 if (!audio_) return false;
1183 return false;
1184 1119
1185 CHECK(IsValidId(source_id_audio_)); 1120 CHECK(IsValidId(source_id_audio_));
1186 if (!audio_->Append(buffers)) 1121 if (!audio_->Append(buffers)) return false;
1187 return false;
1188 1122
1189 IncreaseDurationIfNecessary(buffers, audio_.get()); 1123 IncreaseDurationIfNecessary(buffers, audio_.get());
1190 return true; 1124 return true;
1191 } 1125 }
1192 1126
1193 bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) { 1127 bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) {
1194 lock_.AssertAcquired(); 1128 lock_.AssertAcquired();
1195 DCHECK_NE(state_, SHUTDOWN); 1129 DCHECK_NE(state_, SHUTDOWN);
1196 1130
1197 if (!video_) 1131 if (!video_) return false;
1198 return false;
1199 1132
1200 CHECK(IsValidId(source_id_video_)); 1133 CHECK(IsValidId(source_id_video_));
1201 if (!video_->Append(buffers)) 1134 if (!video_->Append(buffers)) return false;
1202 return false;
1203 1135
1204 IncreaseDurationIfNecessary(buffers, video_.get()); 1136 IncreaseDurationIfNecessary(buffers, video_.get());
1205 return true; 1137 return true;
1206 } 1138 }
1207 1139
1208 bool ChunkDemuxer::OnTextBuffers( 1140 bool ChunkDemuxer::OnTextBuffers(TextTrack* text_track,
1209 TextTrack* text_track, 1141 const StreamParser::BufferQueue& buffers) {
1210 const StreamParser::BufferQueue& buffers) {
1211 lock_.AssertAcquired(); 1142 lock_.AssertAcquired();
1212 DCHECK_NE(state_, SHUTDOWN); 1143 DCHECK_NE(state_, SHUTDOWN);
1213 1144
1214 // TODO(matthewjheaney): IncreaseDurationIfNecessary 1145 // TODO(matthewjheaney): IncreaseDurationIfNecessary
1215 1146
1216 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); 1147 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
1217 itr != buffers.end(); ++itr) { 1148 itr != buffers.end(); ++itr) {
1218 const StreamParserBuffer* const buffer = itr->get(); 1149 const StreamParserBuffer* const buffer = itr->get();
1219 const base::TimeDelta start = buffer->GetTimestamp(); 1150 const base::TimeDelta start = buffer->get_timestamp();
1220 const base::TimeDelta end = start + buffer->GetDuration(); 1151 const base::TimeDelta end = start + buffer->get_duration();
1221 1152
1222 std::string id, settings, content; 1153 std::string id, settings, content;
1223 1154
1224 WebMWebVTTParser::Parse(buffer->GetData(), 1155 WebMWebVTTParser::Parse(buffer->get_data(), buffer->get_data_size(), &id,
1225 buffer->GetDataSize(), 1156 &settings, &content);
1226 &id, &settings, &content);
1227 1157
1228 text_track->addWebVTTCue(start, end, id, content, settings); 1158 text_track->addWebVTTCue(start, end, id, content, settings);
1229 } 1159 }
1230 1160
1231 return true; 1161 return true;
1232 } 1162 }
1233 1163
1234 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that 1164 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that
1235 // this method can be removed and need_key_cb_ can be passed directly 1165 // this method can be removed and need_key_cb_ can be passed directly
1236 // to the parser. 1166 // to the parser.
(...skipping 25 matching lines...) Expand all
1262 } 1192 }
1263 1193
1264 void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) { 1194 void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) {
1265 DCHECK(duration_ != new_duration); 1195 DCHECK(duration_ != new_duration);
1266 user_specified_duration_ = -1; 1196 user_specified_duration_ = -1;
1267 duration_ = new_duration; 1197 duration_ = new_duration;
1268 host_->SetDuration(new_duration); 1198 host_->SetDuration(new_duration);
1269 } 1199 }
1270 1200
1271 void ChunkDemuxer::IncreaseDurationIfNecessary( 1201 void ChunkDemuxer::IncreaseDurationIfNecessary(
1272 const StreamParser::BufferQueue& buffers, 1202 const StreamParser::BufferQueue& buffers, ChunkDemuxerStream* stream) {
1273 ChunkDemuxerStream* stream) {
1274 DCHECK(!buffers.empty()); 1203 DCHECK(!buffers.empty());
1275 if (buffers.back()->GetTimestamp() <= duration_) 1204 if (buffers.back()->get_timestamp() <= duration_) return;
1276 return;
1277 1205
1278 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration()); 1206 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration());
1279 DCHECK_GT(ranges.size(), 0u); 1207 DCHECK_GT(ranges.size(), 0u);
1280 1208
1281 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); 1209 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1282 if (last_timestamp_buffered > duration_) 1210 if (last_timestamp_buffered > duration_)
1283 UpdateDuration(last_timestamp_buffered); 1211 UpdateDuration(last_timestamp_buffered);
1284 } 1212 }
1285 1213
1286 void ChunkDemuxer::DecreaseDurationIfNecessary() { 1214 void ChunkDemuxer::DecreaseDurationIfNecessary() {
1287 Ranges<TimeDelta> ranges = GetBufferedRanges(); 1215 Ranges<TimeDelta> ranges = GetBufferedRanges();
1288 if (ranges.size() == 0u) 1216 if (ranges.size() == 0u) return;
1289 return;
1290 1217
1291 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); 1218 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1292 if (last_timestamp_buffered < duration_) 1219 if (last_timestamp_buffered < duration_)
1293 UpdateDuration(last_timestamp_buffered); 1220 UpdateDuration(last_timestamp_buffered);
1294 } 1221 }
1295 1222
1296 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { 1223 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
1297 if (audio_ && !video_) 1224 if (audio_ && !video_)
1298 return audio_->GetBufferedRanges(duration_); 1225 return audio_->GetBufferedRanges(duration_);
1299 else if (!audio_ && video_) 1226 else if (!audio_ && video_)
1300 return video_->GetBufferedRanges(duration_); 1227 return video_->GetBufferedRanges(duration_);
1301 return ComputeIntersection(); 1228 return ComputeIntersection();
1302 } 1229 }
1303 1230
1304 } // namespace media 1231 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698