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 |