Chromium Code Reviews| 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/base/pipeline.h" | 5 #include "media/base/pipeline.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/synchronization/condition_variable.h" | 18 #include "base/synchronization/condition_variable.h" |
| 19 #include "media/base/audio_decoder.h" | 19 #include "media/base/audio_decoder.h" |
| 20 #include "media/base/audio_renderer.h" | 20 #include "media/base/audio_renderer.h" |
| 21 #include "media/base/clock.h" | 21 #include "media/base/clock.h" |
| 22 #include "media/base/demuxer_stream.h" | |
|
acolwell GONE FROM CHROMIUM
2012/10/15 21:00:07
nit: why is this needed now?
xhwang
2012/10/15 22:52:23
Removed.
| |
| 22 #include "media/base/filter_collection.h" | 23 #include "media/base/filter_collection.h" |
| 23 #include "media/base/media_log.h" | 24 #include "media/base/media_log.h" |
| 24 #include "media/base/video_decoder.h" | 25 #include "media/base/video_decoder.h" |
| 25 #include "media/base/video_decoder_config.h" | 26 #include "media/base/video_decoder_config.h" |
| 26 #include "media/base/video_renderer.h" | 27 #include "media/base/video_renderer.h" |
| 27 | 28 |
| 28 using base::TimeDelta; | 29 using base::TimeDelta; |
| 29 | 30 |
| 30 namespace media { | 31 namespace media { |
| 31 | 32 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 state_ = next_state; | 258 state_ = next_state; |
| 258 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); | 259 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); |
| 259 } | 260 } |
| 260 | 261 |
| 261 #define RETURN_STRING(state) case state: return #state; | 262 #define RETURN_STRING(state) case state: return #state; |
| 262 | 263 |
| 263 const char* Pipeline::GetStateString(State state) { | 264 const char* Pipeline::GetStateString(State state) { |
| 264 switch (state) { | 265 switch (state) { |
| 265 RETURN_STRING(kCreated); | 266 RETURN_STRING(kCreated); |
| 266 RETURN_STRING(kInitDemuxer); | 267 RETURN_STRING(kInitDemuxer); |
| 267 RETURN_STRING(kInitAudioDecoder); | |
| 268 RETURN_STRING(kInitAudioRenderer); | 268 RETURN_STRING(kInitAudioRenderer); |
| 269 RETURN_STRING(kInitVideoRenderer); | 269 RETURN_STRING(kInitVideoRenderer); |
| 270 RETURN_STRING(kInitPrerolling); | 270 RETURN_STRING(kInitPrerolling); |
| 271 RETURN_STRING(kSeeking); | 271 RETURN_STRING(kSeeking); |
| 272 RETURN_STRING(kStarting); | 272 RETURN_STRING(kStarting); |
| 273 RETURN_STRING(kStarted); | 273 RETURN_STRING(kStarted); |
| 274 RETURN_STRING(kStopping); | 274 RETURN_STRING(kStopping); |
| 275 RETURN_STRING(kStopped); | 275 RETURN_STRING(kStopped); |
| 276 } | 276 } |
| 277 NOTREACHED(); | 277 NOTREACHED(); |
| 278 return "INVALID"; | 278 return "INVALID"; |
| 279 } | 279 } |
| 280 | 280 |
| 281 #undef RETURN_STRING | 281 #undef RETURN_STRING |
| 282 | 282 |
| 283 Pipeline::State Pipeline::GetNextState() const { | 283 Pipeline::State Pipeline::GetNextState() const { |
| 284 DCHECK(message_loop_->BelongsToCurrentThread()); | 284 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 285 DCHECK(stop_cb_.is_null()) | 285 DCHECK(stop_cb_.is_null()) |
| 286 << "State transitions don't happen when stopping"; | 286 << "State transitions don't happen when stopping"; |
| 287 DCHECK_EQ(status_, PIPELINE_OK) | 287 DCHECK_EQ(status_, PIPELINE_OK) |
| 288 << "State transitions don't happen when there's an error: " << status_; | 288 << "State transitions don't happen when there's an error: " << status_; |
| 289 | 289 |
| 290 switch (state_) { | 290 switch (state_) { |
| 291 case kCreated: | 291 case kCreated: |
| 292 return kInitDemuxer; | 292 return kInitDemuxer; |
| 293 | 293 |
| 294 case kInitDemuxer: | 294 case kInitDemuxer: |
| 295 if (demuxer_->GetStream(DemuxerStream::AUDIO)) | 295 if (demuxer_->GetStream(DemuxerStream::AUDIO)) |
| 296 return kInitAudioDecoder; | 296 return kInitAudioRenderer; |
| 297 if (demuxer_->GetStream(DemuxerStream::VIDEO)) | 297 if (demuxer_->GetStream(DemuxerStream::VIDEO)) |
| 298 return kInitVideoRenderer; | 298 return kInitVideoRenderer; |
| 299 return kInitPrerolling; | 299 return kInitPrerolling; |
| 300 | 300 |
| 301 case kInitAudioDecoder: | |
| 302 return kInitAudioRenderer; | |
| 303 | |
| 304 case kInitAudioRenderer: | 301 case kInitAudioRenderer: |
| 305 if (demuxer_->GetStream(DemuxerStream::VIDEO)) | 302 if (demuxer_->GetStream(DemuxerStream::VIDEO)) |
| 306 return kInitVideoRenderer; | 303 return kInitVideoRenderer; |
| 307 return kInitPrerolling; | 304 return kInitPrerolling; |
| 308 | 305 |
| 309 case kInitVideoRenderer: | 306 case kInitVideoRenderer: |
| 310 return kInitPrerolling; | 307 return kInitPrerolling; |
| 311 | 308 |
| 312 case kInitPrerolling: | 309 case kInitPrerolling: |
| 313 return kStarting; | 310 return kStarting; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 pending_callbacks_.reset(); | 454 pending_callbacks_.reset(); |
| 458 | 455 |
| 459 PipelineStatusCB done_cb = base::Bind(&Pipeline::OnStateTransition, this); | 456 PipelineStatusCB done_cb = base::Bind(&Pipeline::OnStateTransition, this); |
| 460 | 457 |
| 461 // Switch states, performing any entrance actions for the new state as well. | 458 // Switch states, performing any entrance actions for the new state as well. |
| 462 SetState(GetNextState()); | 459 SetState(GetNextState()); |
| 463 switch (state_) { | 460 switch (state_) { |
| 464 case kInitDemuxer: | 461 case kInitDemuxer: |
| 465 return InitializeDemuxer(done_cb); | 462 return InitializeDemuxer(done_cb); |
| 466 | 463 |
| 467 case kInitAudioDecoder: | |
| 468 return InitializeAudioDecoder(done_cb); | |
| 469 | |
| 470 case kInitAudioRenderer: | 464 case kInitAudioRenderer: |
| 471 return InitializeAudioRenderer(done_cb); | 465 return InitializeAudioRenderer(done_cb); |
| 472 | 466 |
| 473 case kInitVideoRenderer: | 467 case kInitVideoRenderer: |
| 474 return InitializeVideoRenderer(done_cb); | 468 return InitializeVideoRenderer(done_cb); |
| 475 | 469 |
| 476 case kInitPrerolling: | 470 case kInitPrerolling: |
| 477 filter_collection_.reset(); | 471 filter_collection_.reset(); |
| 478 { | 472 { |
| 479 base::AutoLock l(lock_); | 473 base::AutoLock l(lock_); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 DCHECK(message_loop_->BelongsToCurrentThread()); | 620 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 627 DCHECK_EQ(state_, kStopping); | 621 DCHECK_EQ(state_, kStopping); |
| 628 { | 622 { |
| 629 base::AutoLock l(lock_); | 623 base::AutoLock l(lock_); |
| 630 running_ = false; | 624 running_ = false; |
| 631 } | 625 } |
| 632 | 626 |
| 633 SetState(kStopped); | 627 SetState(kStopped); |
| 634 pending_callbacks_.reset(); | 628 pending_callbacks_.reset(); |
| 635 filter_collection_.reset(); | 629 filter_collection_.reset(); |
| 636 audio_decoder_ = NULL; | |
| 637 audio_renderer_ = NULL; | 630 audio_renderer_ = NULL; |
| 638 video_renderer_ = NULL; | 631 video_renderer_ = NULL; |
| 639 demuxer_ = NULL; | 632 demuxer_ = NULL; |
| 640 | 633 |
| 641 // If we stop during initialization/seeking we want to run |seek_cb_| | 634 // If we stop during initialization/seeking we want to run |seek_cb_| |
| 642 // followed by |stop_cb_| so we don't leave outstanding callbacks around. | 635 // followed by |stop_cb_| so we don't leave outstanding callbacks around. |
| 643 if (!seek_cb_.is_null()) { | 636 if (!seek_cb_.is_null()) { |
| 644 base::ResetAndReturn(&seek_cb_).Run(status_); | 637 base::ResetAndReturn(&seek_cb_).Run(status_); |
| 645 error_cb_.Reset(); | 638 error_cb_.Reset(); |
| 646 } | 639 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 StartClockIfWaitingForTimeUpdate_Locked(); | 872 StartClockIfWaitingForTimeUpdate_Locked(); |
| 880 } | 873 } |
| 881 | 874 |
| 882 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { | 875 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { |
| 883 DCHECK(message_loop_->BelongsToCurrentThread()); | 876 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 884 | 877 |
| 885 demuxer_ = filter_collection_->GetDemuxer(); | 878 demuxer_ = filter_collection_->GetDemuxer(); |
| 886 demuxer_->Initialize(this, done_cb); | 879 demuxer_->Initialize(this, done_cb); |
| 887 } | 880 } |
| 888 | 881 |
| 889 void Pipeline::InitializeAudioDecoder(const PipelineStatusCB& done_cb) { | 882 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |
| 890 DCHECK(message_loop_->BelongsToCurrentThread()); | 883 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 891 | 884 |
| 892 scoped_refptr<DemuxerStream> stream = | 885 scoped_refptr<DemuxerStream> stream = |
| 893 demuxer_->GetStream(DemuxerStream::AUDIO); | 886 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 894 DCHECK(stream); | 887 DCHECK(stream); |
| 895 | 888 |
| 896 filter_collection_->SelectAudioDecoder(&audio_decoder_); | |
| 897 audio_decoder_->Initialize( | |
| 898 stream, done_cb, base::Bind(&Pipeline::OnUpdateStatistics, this)); | |
| 899 } | |
| 900 | |
| 901 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { | |
| 902 DCHECK(message_loop_->BelongsToCurrentThread()); | |
| 903 DCHECK(audio_decoder_); | |
| 904 | |
| 905 filter_collection_->SelectAudioRenderer(&audio_renderer_); | 889 filter_collection_->SelectAudioRenderer(&audio_renderer_); |
| 906 audio_renderer_->Initialize( | 890 audio_renderer_->Initialize( |
| 907 audio_decoder_, | 891 stream, |
| 892 *filter_collection_->GetAudioDecoders(), | |
| 908 done_cb, | 893 done_cb, |
| 894 base::Bind(&Pipeline::OnUpdateStatistics, this), | |
| 909 base::Bind(&Pipeline::OnAudioUnderflow, this), | 895 base::Bind(&Pipeline::OnAudioUnderflow, this), |
| 910 base::Bind(&Pipeline::OnAudioTimeUpdate, this), | 896 base::Bind(&Pipeline::OnAudioTimeUpdate, this), |
| 911 base::Bind(&Pipeline::OnAudioRendererEnded, this), | 897 base::Bind(&Pipeline::OnAudioRendererEnded, this), |
| 912 base::Bind(&Pipeline::OnAudioDisabled, this), | 898 base::Bind(&Pipeline::OnAudioDisabled, this), |
| 913 base::Bind(&Pipeline::SetError, this)); | 899 base::Bind(&Pipeline::SetError, this)); |
| 900 filter_collection_->GetAudioDecoders()->clear(); | |
| 914 } | 901 } |
| 915 | 902 |
| 916 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { | 903 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { |
| 917 DCHECK(message_loop_->BelongsToCurrentThread()); | 904 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 918 | 905 |
| 919 scoped_refptr<DemuxerStream> stream = | 906 scoped_refptr<DemuxerStream> stream = |
| 920 demuxer_->GetStream(DemuxerStream::VIDEO); | 907 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 921 DCHECK(stream); | 908 DCHECK(stream); |
| 922 | 909 |
| 923 { | 910 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 959 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 946 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 960 lock_.AssertAcquired(); | 947 lock_.AssertAcquired(); |
| 961 if (!waiting_for_clock_update_) | 948 if (!waiting_for_clock_update_) |
| 962 return; | 949 return; |
| 963 | 950 |
| 964 waiting_for_clock_update_ = false; | 951 waiting_for_clock_update_ = false; |
| 965 clock_->Play(); | 952 clock_->Play(); |
| 966 } | 953 } |
| 967 | 954 |
| 968 } // namespace media | 955 } // namespace media |
| OLD | NEW |