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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 DVLOG(1) << "StartWaitingForSeek()"; | 234 DVLOG(1) << "StartWaitingForSeek()"; |
235 ReadCBQueue read_cbs; | 235 ReadCBQueue read_cbs; |
236 { | 236 { |
237 base::AutoLock auto_lock(lock_); | 237 base::AutoLock auto_lock(lock_); |
238 ChangeState_Locked(WAITING_FOR_SEEK); | 238 ChangeState_Locked(WAITING_FOR_SEEK); |
239 | 239 |
240 std::swap(read_cbs_, read_cbs); | 240 std::swap(read_cbs_, read_cbs); |
241 } | 241 } |
242 | 242 |
243 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) | 243 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) |
244 it->Run(NULL); | 244 it->Run(kAborted, NULL); |
245 } | 245 } |
246 | 246 |
247 void ChunkDemuxerStream::Seek(TimeDelta time) { | 247 void ChunkDemuxerStream::Seek(TimeDelta time) { |
248 base::AutoLock auto_lock(lock_); | 248 base::AutoLock auto_lock(lock_); |
249 | 249 |
250 DCHECK(read_cbs_.empty()); | 250 DCHECK(read_cbs_.empty()); |
251 | 251 |
252 stream_->Seek(time); | 252 stream_->Seek(time); |
253 | 253 |
254 if (state_ == WAITING_FOR_SEEK) | 254 if (state_ == WAITING_FOR_SEEK) |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 ReadCBQueue read_cbs; | 357 ReadCBQueue read_cbs; |
358 { | 358 { |
359 base::AutoLock auto_lock(lock_); | 359 base::AutoLock auto_lock(lock_); |
360 ChangeState_Locked(SHUTDOWN); | 360 ChangeState_Locked(SHUTDOWN); |
361 std::swap(read_cbs_, read_cbs); | 361 std::swap(read_cbs_, read_cbs); |
362 } | 362 } |
363 | 363 |
364 // Pass end of stream buffers to all callbacks to signal that no more data | 364 // Pass end of stream buffers to all callbacks to signal that no more data |
365 // will be sent. | 365 // will be sent. |
366 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) | 366 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) |
367 it->Run(StreamParserBuffer::CreateEOSBuffer()); | 367 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer()); |
368 } | 368 } |
369 | 369 |
370 // Helper function that makes sure |read_cb| runs on |message_loop|. | 370 // Helper function that makes sure |read_cb| runs on |message_loop|. |
371 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb, | 371 static void RunOnMessageLoop(const DemuxerStream::ReadCB& read_cb, |
372 MessageLoop* message_loop, | 372 MessageLoop* message_loop, |
| 373 DemuxerStream::Status status, |
373 const scoped_refptr<DecoderBuffer>& buffer) { | 374 const scoped_refptr<DecoderBuffer>& buffer) { |
374 if (MessageLoop::current() != message_loop) { | 375 if (MessageLoop::current() != message_loop) { |
375 message_loop->PostTask(FROM_HERE, base::Bind( | 376 message_loop->PostTask(FROM_HERE, base::Bind( |
376 &RunOnMessageLoop, read_cb, message_loop, buffer)); | 377 &RunOnMessageLoop, read_cb, message_loop, status, buffer)); |
377 return; | 378 return; |
378 } | 379 } |
379 | 380 |
380 read_cb.Run(buffer); | 381 read_cb.Run(status, buffer); |
381 } | 382 } |
382 | 383 |
383 // DemuxerStream methods. | 384 // DemuxerStream methods. |
384 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { | 385 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { |
| 386 DemuxerStream::Status status = kOk; |
385 scoped_refptr<StreamParserBuffer> buffer; | 387 scoped_refptr<StreamParserBuffer> buffer; |
386 { | 388 { |
387 base::AutoLock auto_lock(lock_); | 389 base::AutoLock auto_lock(lock_); |
388 | 390 |
389 switch (state_) { | 391 switch (state_) { |
390 case RETURNING_DATA_FOR_READS: | 392 case RETURNING_DATA_FOR_READS: |
391 // If we already have pending reads or we don't have any buffers ready, | 393 // If we already have pending reads or we don't have any buffers ready, |
392 // then defer this read. | 394 // then defer this read. |
393 if (!read_cbs_.empty() || !stream_->GetNextBuffer(&buffer)) { | 395 if (!read_cbs_.empty() || !stream_->GetNextBuffer(&buffer)) { |
394 DeferRead_Locked(read_cb); | 396 DeferRead_Locked(read_cb); |
395 return; | 397 return; |
396 } | 398 } |
397 break; | 399 break; |
398 case WAITING_FOR_SEEK: | 400 case WAITING_FOR_SEEK: |
399 // Null buffers should be returned in this state since we are waiting | 401 // Null buffers should be returned in this state since we are waiting |
400 // for a seek. Any buffers in the SourceBuffer should NOT be returned | 402 // for a seek. Any buffers in the SourceBuffer should NOT be returned |
401 // because they are associated with the seek. | 403 // because they are associated with the seek. |
402 DCHECK(read_cbs_.empty()); | 404 DCHECK(read_cbs_.empty()); |
| 405 status = kAborted; |
403 break; | 406 break; |
404 case SHUTDOWN: | 407 case SHUTDOWN: |
405 DCHECK(read_cbs_.empty()); | 408 DCHECK(read_cbs_.empty()); |
406 buffer = StreamParserBuffer::CreateEOSBuffer(); | 409 buffer = StreamParserBuffer::CreateEOSBuffer(); |
407 } | 410 } |
408 } | 411 } |
409 | 412 |
410 read_cb.Run(buffer); | 413 read_cb.Run(status, buffer); |
411 } | 414 } |
412 | 415 |
413 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } | 416 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } |
414 | 417 |
415 void ChunkDemuxerStream::EnableBitstreamConverter() {} | 418 void ChunkDemuxerStream::EnableBitstreamConverter() {} |
416 | 419 |
417 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { | 420 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { |
418 CHECK_EQ(type_, AUDIO); | 421 CHECK_EQ(type_, AUDIO); |
419 base::AutoLock auto_lock(lock_); | 422 base::AutoLock auto_lock(lock_); |
420 return stream_->GetCurrentAudioDecoderConfig(); | 423 return stream_->GetCurrentAudioDecoderConfig(); |
(...skipping 23 matching lines...) Expand all Loading... |
444 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { | 447 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { |
445 lock_.AssertAcquired(); | 448 lock_.AssertAcquired(); |
446 | 449 |
447 if (state_ != RETURNING_DATA_FOR_READS) | 450 if (state_ != RETURNING_DATA_FOR_READS) |
448 return; | 451 return; |
449 | 452 |
450 scoped_refptr<StreamParserBuffer> buffer; | 453 scoped_refptr<StreamParserBuffer> buffer; |
451 while (!read_cbs_.empty()) { | 454 while (!read_cbs_.empty()) { |
452 if (!stream_->GetNextBuffer(&buffer)) | 455 if (!stream_->GetNextBuffer(&buffer)) |
453 return; | 456 return; |
454 closures->push_back(base::Bind(read_cbs_.front(), buffer)); | 457 closures->push_back(base::Bind(read_cbs_.front(), |
| 458 DemuxerStream::kOk, buffer)); |
455 read_cbs_.pop_front(); | 459 read_cbs_.pop_front(); |
456 } | 460 } |
457 } | 461 } |
458 | 462 |
459 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 463 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
460 : state_(WAITING_FOR_INIT), | 464 : state_(WAITING_FOR_INIT), |
461 host_(NULL), | 465 host_(NULL), |
462 client_(client) { | 466 client_(client) { |
463 DCHECK(client); | 467 DCHECK(client); |
464 } | 468 } |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 // TODO(vrk): There should be a special case for the first appends where all | 982 // TODO(vrk): There should be a special case for the first appends where all |
979 // streams (for both demuxed and muxed case) begin at the earliest stream | 983 // streams (for both demuxed and muxed case) begin at the earliest stream |
980 // timestamp. (crbug.com/132815) | 984 // timestamp. (crbug.com/132815) |
981 if (audio_ && source_id == source_id_audio_) | 985 if (audio_ && source_id == source_id_audio_) |
982 audio_->OnNewMediaSegment(start_timestamp); | 986 audio_->OnNewMediaSegment(start_timestamp); |
983 if (video_ && source_id == source_id_video_) | 987 if (video_ && source_id == source_id_video_) |
984 video_->OnNewMediaSegment(start_timestamp); | 988 video_->OnNewMediaSegment(start_timestamp); |
985 } | 989 } |
986 | 990 |
987 } // namespace media | 991 } // namespace media |
OLD | NEW |