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 "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 read_cbs_.pop_front(); | 328 read_cbs_.pop_front(); |
329 } | 329 } |
330 | 330 |
331 ChangeState_Locked(RETURNING_EOS_FOR_READS); | 331 ChangeState_Locked(RETURNING_EOS_FOR_READS); |
332 } | 332 } |
333 | 333 |
334 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 334 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
335 : state_(WAITING_FOR_INIT), | 335 : state_(WAITING_FOR_INIT), |
336 client_(client), | 336 client_(client), |
337 buffered_bytes_(0), | 337 buffered_bytes_(0), |
338 seek_waits_for_data_(true), | 338 seek_waits_for_data_(true) { |
339 deferred_error_(PIPELINE_OK) { | |
340 DCHECK(client); | 339 DCHECK(client); |
341 } | 340 } |
342 | 341 |
343 ChunkDemuxer::~ChunkDemuxer() { | 342 ChunkDemuxer::~ChunkDemuxer() { |
344 DCHECK_NE(state_, INITIALIZED); | 343 DCHECK_NE(state_, INITIALIZED); |
345 } | 344 } |
346 | 345 |
347 void ChunkDemuxer::Init(const PipelineStatusCB& cb) { | 346 void ChunkDemuxer::Initialize(const PipelineStatusCB& cb) { |
348 DVLOG(1) << "Init()"; | 347 DVLOG(1) << "Init()"; |
349 { | 348 { |
350 base::AutoLock auto_lock(lock_); | 349 base::AutoLock auto_lock(lock_); |
351 DCHECK_EQ(state_, WAITING_FOR_INIT); | 350 DCHECK_EQ(state_, WAITING_FOR_INIT); |
352 | 351 |
353 ChangeState_Locked(INITIALIZING); | 352 ChangeState_Locked(INITIALIZING); |
354 init_cb_ = cb; | 353 init_cb_ = cb; |
355 stream_parser_.reset(new WebMStreamParser()); | 354 stream_parser_.reset(new WebMStreamParser()); |
356 | 355 |
357 stream_parser_->Init( | 356 stream_parser_->Init( |
358 base::Bind(&ChunkDemuxer::OnStreamParserInitDone, this), | 357 base::Bind(&ChunkDemuxer::OnStreamParserInitDone, this), |
359 this); | 358 this); |
360 } | 359 } |
361 | 360 |
362 client_->DemuxerOpened(this); | 361 client_->DemuxerOpened(this); |
363 } | 362 } |
364 | 363 |
365 void ChunkDemuxer::set_host(DemuxerHost* host) { | |
366 DCHECK(state_ == INITIALIZED || state_ == PARSE_ERROR); | |
367 Demuxer::set_host(host); | |
368 host->SetDuration(duration_); | |
369 host->SetCurrentReadPosition(0); | |
370 if (deferred_error_ != PIPELINE_OK) { | |
371 host->OnDemuxerError(deferred_error_); | |
372 deferred_error_ = PIPELINE_OK; | |
373 } | |
374 } | |
375 | |
376 void ChunkDemuxer::Stop(const base::Closure& callback) { | 364 void ChunkDemuxer::Stop(const base::Closure& callback) { |
377 DVLOG(1) << "Stop()"; | 365 DVLOG(1) << "Stop()"; |
378 Shutdown(); | 366 Shutdown(); |
379 callback.Run(); | 367 callback.Run(); |
380 } | 368 } |
381 | 369 |
382 void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 370 void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
383 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; | 371 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; |
384 | 372 |
385 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; | 373 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; |
(...skipping 18 matching lines...) Expand all Loading... |
404 } | 392 } |
405 | 393 |
406 cb.Run(status); | 394 cb.Run(status); |
407 } | 395 } |
408 | 396 |
409 void ChunkDemuxer::OnAudioRendererDisabled() { | 397 void ChunkDemuxer::OnAudioRendererDisabled() { |
410 base::AutoLock auto_lock(lock_); | 398 base::AutoLock auto_lock(lock_); |
411 audio_ = NULL; | 399 audio_ = NULL; |
412 } | 400 } |
413 | 401 |
414 void ChunkDemuxer::SetPreload(Preload preload) {} | |
415 | |
416 int ChunkDemuxer::GetBitrate() { | 402 int ChunkDemuxer::GetBitrate() { |
417 // TODO(acolwell): Implement bitrate reporting. | 403 // TODO(acolwell): Implement bitrate reporting. |
418 return 0; | 404 return 0; |
419 } | 405 } |
420 | 406 |
421 bool ChunkDemuxer::IsLocalSource() { | 407 bool ChunkDemuxer::IsLocalSource() { |
422 // TODO(acolwell): Report whether source is local or not. | 408 // TODO(acolwell): Report whether source is local or not. |
423 return false; | 409 return false; |
424 } | 410 } |
425 | 411 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 530 |
545 if (video_.get() && video_->GetLastBufferTimestamp(&tmp) && | 531 if (video_.get() && video_->GetLastBufferTimestamp(&tmp) && |
546 tmp > buffered_ts) { | 532 tmp > buffered_ts) { |
547 buffered_ts = tmp; | 533 buffered_ts = tmp; |
548 } | 534 } |
549 | 535 |
550 buffered_bytes = buffered_bytes_; | 536 buffered_bytes = buffered_bytes_; |
551 } | 537 } |
552 | 538 |
553 // Notify the host of 'network activity' because we got data. | 539 // Notify the host of 'network activity' because we got data. |
554 if (host()) { | 540 host()->SetBufferedBytes(buffered_bytes); |
555 host()->SetBufferedBytes(buffered_bytes); | |
556 | 541 |
557 if (buffered_ts.InSeconds() >= 0) { | 542 if (buffered_ts.InSeconds() >= 0) { |
558 host()->SetBufferedTime(buffered_ts); | 543 host()->SetBufferedTime(buffered_ts); |
559 } | 544 } |
560 | 545 |
561 host()->SetNetworkActivity(true); | 546 host()->SetNetworkActivity(true); |
562 } | |
563 | 547 |
564 if (!cb.is_null()) | 548 if (!cb.is_null()) |
565 cb.Run(PIPELINE_OK); | 549 cb.Run(PIPELINE_OK); |
566 | 550 |
567 return true; | 551 return true; |
568 } | 552 } |
569 | 553 |
570 void ChunkDemuxer::EndOfStream(PipelineStatus status) { | 554 void ChunkDemuxer::EndOfStream(PipelineStatus status) { |
571 DVLOG(1) << "EndOfStream(" << status << ")"; | 555 DVLOG(1) << "EndOfStream(" << status << ")"; |
572 base::AutoLock auto_lock(lock_); | 556 base::AutoLock auto_lock(lock_); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 if (video_.get()) | 641 if (video_.get()) |
658 video_->Shutdown(); | 642 video_->Shutdown(); |
659 } | 643 } |
660 | 644 |
661 if (!cb.is_null()) { | 645 if (!cb.is_null()) { |
662 base::AutoUnlock auto_unlock(lock_); | 646 base::AutoUnlock auto_unlock(lock_); |
663 cb.Run(error); | 647 cb.Run(error); |
664 return; | 648 return; |
665 } | 649 } |
666 | 650 |
667 DemuxerHost* demuxer_host = host(); | 651 base::AutoUnlock auto_unlock(lock_); |
668 if (demuxer_host) { | 652 host()->OnDemuxerError(error); |
669 base::AutoUnlock auto_unlock(lock_); | |
670 demuxer_host->OnDemuxerError(error); | |
671 return; | |
672 } | |
673 | |
674 deferred_error_ = error; | |
675 } | 653 } |
676 | 654 |
677 void ChunkDemuxer::OnStreamParserInitDone(bool success, | 655 void ChunkDemuxer::OnStreamParserInitDone(bool success, |
678 base::TimeDelta duration) { | 656 base::TimeDelta duration) { |
679 lock_.AssertAcquired(); | 657 lock_.AssertAcquired(); |
680 DCHECK_EQ(state_, INITIALIZING); | 658 DCHECK_EQ(state_, INITIALIZING); |
681 if (!success || (!audio_.get() && !video_.get())) { | 659 if (!success || (!audio_.get() && !video_.get())) { |
682 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | 660 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
683 return; | 661 return; |
684 } | 662 } |
685 | 663 |
686 duration_ = duration; | 664 duration_ = duration; |
| 665 host()->SetDuration(duration_); |
| 666 host()->SetCurrentReadPosition(0); |
687 | 667 |
688 ChangeState_Locked(INITIALIZED); | 668 ChangeState_Locked(INITIALIZED); |
689 PipelineStatusCB cb; | 669 PipelineStatusCB cb; |
690 std::swap(cb, init_cb_); | 670 std::swap(cb, init_cb_); |
691 cb.Run(PIPELINE_OK); | 671 cb.Run(PIPELINE_OK); |
692 } | 672 } |
693 | 673 |
694 bool ChunkDemuxer::OnNewAudioConfig(const AudioDecoderConfig& config) { | 674 bool ChunkDemuxer::OnNewAudioConfig(const AudioDecoderConfig& config) { |
695 lock_.AssertAcquired(); | 675 lock_.AssertAcquired(); |
696 // Only allow a single audio config for now. | 676 // Only allow a single audio config for now. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 if (!video_->CanAddBuffers(buffers)) | 711 if (!video_->CanAddBuffers(buffers)) |
732 return false; | 712 return false; |
733 | 713 |
734 video_->AddBuffers(buffers); | 714 video_->AddBuffers(buffers); |
735 seek_waits_for_data_ = false; | 715 seek_waits_for_data_ = false; |
736 | 716 |
737 return true; | 717 return true; |
738 } | 718 } |
739 | 719 |
740 } // namespace media | 720 } // namespace media |
OLD | NEW |