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" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 while (!notified_) | 47 while (!notified_) |
48 cv_.Wait(); | 48 cv_.Wait(); |
49 } | 49 } |
50 | 50 |
51 media::PipelineStatus PipelineStatusNotification::status() { | 51 media::PipelineStatus PipelineStatusNotification::status() { |
52 base::AutoLock auto_lock(lock_); | 52 base::AutoLock auto_lock(lock_); |
53 DCHECK(notified_); | 53 DCHECK(notified_); |
54 return status_; | 54 return status_; |
55 } | 55 } |
56 | 56 |
57 class Pipeline::PipelineInitState { | 57 struct Pipeline::PipelineInitState { |
58 public: | |
59 scoped_refptr<AudioDecoder> audio_decoder_; | |
60 scoped_refptr<VideoDecoder> video_decoder_; | 58 scoped_refptr<VideoDecoder> video_decoder_; |
61 scoped_refptr<CompositeFilter> composite_; | 59 scoped_refptr<CompositeFilter> composite_; |
62 }; | 60 }; |
63 | 61 |
64 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) | 62 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) |
65 : message_loop_(message_loop), | 63 : message_loop_(message_loop), |
66 media_log_(media_log), | 64 media_log_(media_log), |
67 clock_(new Clock(&base::Time::Now)), | 65 clock_(new Clock(&base::Time::Now)), |
68 waiting_for_clock_update_(false), | 66 waiting_for_clock_update_(false), |
69 state_(kCreated), | 67 state_(kCreated), |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
676 // If this method returns false, then there's no audio stream. | 674 // If this method returns false, then there's no audio stream. |
677 if (InitializeAudioDecoder(demuxer_)) | 675 if (InitializeAudioDecoder(demuxer_)) |
678 return; | 676 return; |
679 } | 677 } |
680 | 678 |
681 // Assuming audio decoder was created, create audio renderer. | 679 // Assuming audio decoder was created, create audio renderer. |
682 if (state_ == kInitAudioDecoder) { | 680 if (state_ == kInitAudioDecoder) { |
683 SetState(kInitAudioRenderer); | 681 SetState(kInitAudioRenderer); |
684 | 682 |
685 // Returns false if there's no audio stream. | 683 // Returns false if there's no audio stream. |
686 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder_)) { | 684 if (InitializeAudioRenderer(audio_decoder_)) { |
687 base::AutoLock auto_lock(lock_); | 685 base::AutoLock auto_lock(lock_); |
688 has_audio_ = true; | 686 has_audio_ = true; |
scherkus (not reviewing)
2012/02/03 23:31:29
I wonder if we can replace has_audio_/has_video_ w
Ami GONE FROM CHROMIUM
2012/02/04 00:10:21
TODO'd.
| |
689 return; | 687 return; |
690 } | 688 } |
691 } | 689 } |
692 | 690 |
693 // Assuming audio renderer was created, create video decoder. | 691 // Assuming audio renderer was created, create video decoder. |
694 if (state_ == kInitAudioRenderer) { | 692 if (state_ == kInitAudioRenderer) { |
695 // Then perform the stage of initialization, i.e. initialize video decoder. | 693 // Then perform the stage of initialization, i.e. initialize video decoder. |
696 SetState(kInitVideoDecoder); | 694 SetState(kInitVideoDecoder); |
697 if (InitializeVideoDecoder(demuxer_)) | 695 if (InitializeVideoDecoder(demuxer_)) |
698 return; | 696 return; |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 // We use audio stream to update the clock. So if there is such a stream, | 1020 // We use audio stream to update the clock. So if there is such a stream, |
1023 // we pause the clock until we receive a valid timestamp. | 1021 // we pause the clock until we receive a valid timestamp. |
1024 waiting_for_clock_update_ = true; | 1022 waiting_for_clock_update_ = true; |
1025 if (!has_audio_) { | 1023 if (!has_audio_) { |
1026 clock_->SetMaxTime(clock_->Duration()); | 1024 clock_->SetMaxTime(clock_->Duration()); |
1027 StartClockIfWaitingForTimeUpdate_Locked(); | 1025 StartClockIfWaitingForTimeUpdate_Locked(); |
1028 } | 1026 } |
1029 | 1027 |
1030 // Start monitoring rate of downloading. | 1028 // Start monitoring rate of downloading. |
1031 int bitrate = 0; | 1029 int bitrate = 0; |
1032 if (demuxer_.get()) { | 1030 if (demuxer_) { |
1033 bitrate = demuxer_->GetBitrate(); | 1031 bitrate = demuxer_->GetBitrate(); |
1034 local_source_ = demuxer_->IsLocalSource(); | 1032 local_source_ = demuxer_->IsLocalSource(); |
1035 streaming_ = !demuxer_->IsSeekable(); | 1033 streaming_ = !demuxer_->IsSeekable(); |
1036 } | 1034 } |
1037 // Needs to be locked because most other calls to |download_rate_monitor_| | 1035 // Needs to be locked because most other calls to |download_rate_monitor_| |
1038 // occur on the renderer thread. | 1036 // occur on the renderer thread. |
1039 download_rate_monitor_.Start( | 1037 download_rate_monitor_.Start( |
1040 base::Bind(&Pipeline::OnCanPlayThrough, this), | 1038 base::Bind(&Pipeline::OnCanPlayThrough, this), |
1041 bitrate, streaming_, local_source_); | 1039 bitrate, streaming_, local_source_); |
1042 download_rate_monitor_.SetBufferedBytes(buffered_bytes_, base::Time::Now()); | 1040 download_rate_monitor_.SetBufferedBytes(buffered_bytes_, base::Time::Now()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1084 // default: intentionally left out to force new states to cause compiler | 1082 // default: intentionally left out to force new states to cause compiler |
1085 // errors. | 1083 // errors. |
1086 }; | 1084 }; |
1087 } | 1085 } |
1088 | 1086 |
1089 void Pipeline::FinishDestroyingFiltersTask() { | 1087 void Pipeline::FinishDestroyingFiltersTask() { |
1090 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1088 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1091 DCHECK(IsPipelineStopped()); | 1089 DCHECK(IsPipelineStopped()); |
1092 | 1090 |
1093 // Clear filter references. | 1091 // Clear filter references. |
1092 audio_decoder_ = NULL; | |
1094 audio_renderer_ = NULL; | 1093 audio_renderer_ = NULL; |
1095 video_renderer_ = NULL; | 1094 video_renderer_ = NULL; |
1096 demuxer_ = NULL; | 1095 demuxer_ = NULL; |
1097 | 1096 |
1098 pipeline_filter_ = NULL; | 1097 pipeline_filter_ = NULL; |
1099 | 1098 |
1100 if (error_caused_teardown_ && !IsPipelineOk() && !error_callback_.is_null()) | 1099 if (error_caused_teardown_ && !IsPipelineOk() && !error_callback_.is_null()) |
1101 error_callback_.Run(status_); | 1100 error_callback_.Run(status_); |
1102 | 1101 |
1103 if (stop_pending_) { | 1102 if (stop_pending_) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 const scoped_refptr<Demuxer>& demuxer) { | 1163 const scoped_refptr<Demuxer>& demuxer) { |
1165 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1164 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1166 DCHECK(IsPipelineOk()); | 1165 DCHECK(IsPipelineOk()); |
1167 | 1166 |
1168 scoped_refptr<DemuxerStream> stream = | 1167 scoped_refptr<DemuxerStream> stream = |
1169 demuxer->GetStream(DemuxerStream::AUDIO); | 1168 demuxer->GetStream(DemuxerStream::AUDIO); |
1170 | 1169 |
1171 if (!stream) | 1170 if (!stream) |
1172 return false; | 1171 return false; |
1173 | 1172 |
1174 scoped_refptr<AudioDecoder> audio_decoder; | 1173 filter_collection_->SelectAudioDecoder(&audio_decoder_); |
1175 filter_collection_->SelectAudioDecoder(&audio_decoder); | |
1176 | 1174 |
1177 if (!audio_decoder) { | 1175 if (!audio_decoder_) { |
1178 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1176 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1179 return false; | 1177 return false; |
1180 } | 1178 } |
1181 | 1179 |
1182 if (!PrepareFilter(audio_decoder)) | 1180 audio_decoder_->Initialize( |
1183 return false; | |
1184 | |
1185 pipeline_init_state_->audio_decoder_ = audio_decoder; | |
1186 audio_decoder->Initialize( | |
1187 stream, | 1181 stream, |
1188 base::Bind(&Pipeline::OnFilterInitialize, this), | 1182 base::Bind(&Pipeline::OnFilterInitialize, this), |
1189 base::Bind(&Pipeline::OnUpdateStatistics, this)); | 1183 base::Bind(&Pipeline::OnUpdateStatistics, this)); |
1190 return true; | 1184 return true; |
1191 } | 1185 } |
1192 | 1186 |
1193 bool Pipeline::InitializeVideoDecoder( | 1187 bool Pipeline::InitializeVideoDecoder( |
1194 const scoped_refptr<Demuxer>& demuxer) { | 1188 const scoped_refptr<Demuxer>& demuxer) { |
1195 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1189 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1196 DCHECK(IsPipelineOk()); | 1190 DCHECK(IsPipelineOk()); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1425 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 1419 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
1426 lock_.AssertAcquired(); | 1420 lock_.AssertAcquired(); |
1427 if (!waiting_for_clock_update_) | 1421 if (!waiting_for_clock_update_) |
1428 return; | 1422 return; |
1429 | 1423 |
1430 waiting_for_clock_update_ = false; | 1424 waiting_for_clock_update_ = false; |
1431 clock_->Play(); | 1425 clock_->Play(); |
1432 } | 1426 } |
1433 | 1427 |
1434 } // namespace media | 1428 } // namespace media |
OLD | NEW |