OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, | 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, |
6 // potential deadlocks, etc... | 6 // potential deadlocks, etc... |
7 | 7 |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/condition_variable.h" | 10 #include "base/condition_variable.h" |
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 } else { | 930 } else { |
931 // Destroying filters due to SetError(). | 931 // Destroying filters due to SetError(). |
932 state_ = kError; | 932 state_ = kError; |
933 // If our owner has requested to be notified of an error. | 933 // If our owner has requested to be notified of an error. |
934 if (error_callback_.get()) { | 934 if (error_callback_.get()) { |
935 error_callback_->Run(); | 935 error_callback_->Run(); |
936 } | 936 } |
937 } | 937 } |
938 } | 938 } |
939 | 939 |
940 void PipelineImpl::PrepareFilter(scoped_refptr<MediaFilter> filter) { | 940 bool PipelineImpl::PrepareFilter(scoped_refptr<MediaFilter> filter) { |
941 DCHECK_EQ(MessageLoop::current(), message_loop_); | 941 DCHECK_EQ(MessageLoop::current(), message_loop_); |
942 DCHECK(IsPipelineOk()); | 942 DCHECK(IsPipelineOk()); |
943 | 943 |
944 // Create a dedicated thread for this filter if applicable. | 944 // Create a dedicated thread for this filter if applicable. |
945 if (filter->requires_message_loop()) { | 945 if (filter->requires_message_loop()) { |
946 scoped_ptr<base::Thread> thread( | 946 scoped_ptr<base::Thread> thread( |
947 new base::Thread(filter->message_loop_name())); | 947 new base::Thread(filter->message_loop_name())); |
948 if (!thread.get() || !thread->Start()) { | 948 if (!thread.get() || !thread->Start()) { |
949 NOTREACHED() << "Could not start filter thread"; | 949 NOTREACHED() << "Could not start filter thread"; |
950 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); | 950 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); |
951 return; | 951 return false; |
952 } | 952 } |
953 | 953 |
954 filter->set_message_loop(thread->message_loop()); | 954 filter->set_message_loop(thread->message_loop()); |
955 filter_threads_.push_back(thread.release()); | 955 filter_threads_.push_back(thread.release()); |
956 } | 956 } |
957 | 957 |
958 // Register ourselves as the filter's host. | 958 // Register ourselves as the filter's host. |
959 DCHECK(IsPipelineOk()); | 959 DCHECK(IsPipelineOk()); |
960 filter->set_host(this); | 960 filter->set_host(this); |
961 filters_.push_back(make_scoped_refptr(filter.get())); | 961 filters_.push_back(make_scoped_refptr(filter.get())); |
| 962 return true; |
962 } | 963 } |
963 | 964 |
964 void PipelineImpl::InitializeDataSource() { | 965 void PipelineImpl::InitializeDataSource() { |
965 DCHECK_EQ(MessageLoop::current(), message_loop_); | 966 DCHECK_EQ(MessageLoop::current(), message_loop_); |
966 DCHECK(IsPipelineOk()); | 967 DCHECK(IsPipelineOk()); |
967 | 968 |
968 scoped_refptr<DataSource> data_source; | 969 scoped_refptr<DataSource> data_source; |
969 while (true) { | 970 while (true) { |
970 filter_collection_->SelectDataSource(&data_source); | 971 filter_collection_->SelectDataSource(&data_source); |
971 if (!data_source || data_source->IsUrlSupported(url_)) | 972 if (!data_source || data_source->IsUrlSupported(url_)) |
972 break; | 973 break; |
973 } | 974 } |
974 | 975 |
975 if (!data_source) { | 976 if (!data_source) { |
976 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 977 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
977 return; | 978 return; |
978 } | 979 } |
979 | 980 |
980 PrepareFilter(data_source); | 981 if (!PrepareFilter(data_source)) { |
| 982 return; |
| 983 } |
| 984 |
981 pipeline_init_state_->data_source_ = data_source; | 985 pipeline_init_state_->data_source_ = data_source; |
982 data_source->Initialize( | 986 data_source->Initialize( |
983 url_, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 987 url_, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
984 } | 988 } |
985 | 989 |
986 void PipelineImpl::InitializeDemuxer( | 990 void PipelineImpl::InitializeDemuxer( |
987 const scoped_refptr<DataSource>& data_source) { | 991 const scoped_refptr<DataSource>& data_source) { |
988 DCHECK_EQ(MessageLoop::current(), message_loop_); | 992 DCHECK_EQ(MessageLoop::current(), message_loop_); |
989 DCHECK(IsPipelineOk()); | 993 DCHECK(IsPipelineOk()); |
990 | 994 |
991 scoped_refptr<Demuxer> demuxer; | 995 scoped_refptr<Demuxer> demuxer; |
992 | 996 |
993 CHECK(data_source); | 997 CHECK(data_source); |
994 | 998 |
995 filter_collection_->SelectDemuxer(&demuxer); | 999 filter_collection_->SelectDemuxer(&demuxer); |
996 if (!demuxer) { | 1000 if (!demuxer) { |
997 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1001 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
998 return; | 1002 return; |
999 } | 1003 } |
1000 | 1004 |
1001 PrepareFilter(demuxer); | 1005 if (!PrepareFilter(demuxer)) { |
| 1006 return; |
| 1007 } |
| 1008 |
1002 pipeline_init_state_->demuxer_ = demuxer; | 1009 pipeline_init_state_->demuxer_ = demuxer; |
1003 demuxer->Initialize(data_source, | 1010 demuxer->Initialize(data_source, |
1004 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1011 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
1005 } | 1012 } |
1006 | 1013 |
1007 bool PipelineImpl::InitializeAudioDecoder( | 1014 bool PipelineImpl::InitializeAudioDecoder( |
1008 const scoped_refptr<Demuxer>& demuxer) { | 1015 const scoped_refptr<Demuxer>& demuxer) { |
1009 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1016 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1010 DCHECK(IsPipelineOk()); | 1017 DCHECK(IsPipelineOk()); |
1011 | 1018 |
1012 scoped_refptr<DemuxerStream> stream = | 1019 scoped_refptr<DemuxerStream> stream = |
1013 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); | 1020 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); |
1014 | 1021 |
1015 if (stream) { | 1022 if (!stream) |
1016 scoped_refptr<AudioDecoder> audio_decoder; | 1023 return false; |
1017 filter_collection_->SelectAudioDecoder(&audio_decoder); | |
1018 | 1024 |
1019 if (audio_decoder) { | 1025 scoped_refptr<AudioDecoder> audio_decoder; |
1020 PrepareFilter(audio_decoder); | 1026 filter_collection_->SelectAudioDecoder(&audio_decoder); |
1021 pipeline_init_state_->audio_decoder_ = audio_decoder; | 1027 |
1022 audio_decoder->Initialize( | 1028 if (!audio_decoder) { |
1023 stream, | 1029 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1024 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1030 return false; |
1025 return true; | |
1026 } else { | |
1027 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
1028 } | |
1029 } | 1031 } |
1030 | 1032 |
1031 return false; | 1033 if (!PrepareFilter(audio_decoder)) |
| 1034 return false; |
| 1035 |
| 1036 pipeline_init_state_->audio_decoder_ = audio_decoder; |
| 1037 audio_decoder->Initialize( |
| 1038 stream, |
| 1039 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1040 return true; |
1032 } | 1041 } |
1033 | 1042 |
1034 bool PipelineImpl::InitializeVideoDecoder( | 1043 bool PipelineImpl::InitializeVideoDecoder( |
1035 const scoped_refptr<Demuxer>& demuxer) { | 1044 const scoped_refptr<Demuxer>& demuxer) { |
1036 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1045 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1037 DCHECK(IsPipelineOk()); | 1046 DCHECK(IsPipelineOk()); |
1038 | 1047 |
1039 scoped_refptr<DemuxerStream> stream = | 1048 scoped_refptr<DemuxerStream> stream = |
1040 FindDemuxerStream(demuxer, mime_type::kMajorTypeVideo); | 1049 FindDemuxerStream(demuxer, mime_type::kMajorTypeVideo); |
1041 | 1050 |
1042 if (stream) { | 1051 if (!stream) |
1043 scoped_refptr<VideoDecoder> video_decoder; | 1052 return false; |
1044 filter_collection_->SelectVideoDecoder(&video_decoder); | |
1045 | 1053 |
1046 if (video_decoder) { | 1054 scoped_refptr<VideoDecoder> video_decoder; |
1047 PrepareFilter(video_decoder); | 1055 filter_collection_->SelectVideoDecoder(&video_decoder); |
1048 pipeline_init_state_->video_decoder_ = video_decoder; | 1056 |
1049 video_decoder->Initialize( | 1057 if (!video_decoder) { |
1050 stream, | 1058 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1051 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1059 return false; |
1052 return true; | |
1053 } else { | |
1054 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
1055 } | |
1056 } | 1060 } |
1057 return false; | 1061 |
| 1062 if (!PrepareFilter(video_decoder)) |
| 1063 return false; |
| 1064 |
| 1065 pipeline_init_state_->video_decoder_ = video_decoder; |
| 1066 video_decoder->Initialize( |
| 1067 stream, |
| 1068 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1069 return true; |
1058 } | 1070 } |
1059 | 1071 |
1060 bool PipelineImpl::InitializeAudioRenderer( | 1072 bool PipelineImpl::InitializeAudioRenderer( |
1061 const scoped_refptr<AudioDecoder>& decoder) { | 1073 const scoped_refptr<AudioDecoder>& decoder) { |
1062 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1074 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1063 DCHECK(IsPipelineOk()); | 1075 DCHECK(IsPipelineOk()); |
1064 | 1076 |
1065 if (decoder) { | 1077 if (!decoder) |
1066 filter_collection_->SelectAudioRenderer(&audio_renderer_); | 1078 return false; |
1067 | 1079 |
1068 if (audio_renderer_) { | 1080 filter_collection_->SelectAudioRenderer(&audio_renderer_); |
1069 PrepareFilter(audio_renderer_); | 1081 if (!audio_renderer_) { |
1070 audio_renderer_->Initialize( | 1082 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1071 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1083 return false; |
1072 return true; | |
1073 } else { | |
1074 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
1075 } | |
1076 } | 1084 } |
1077 return false; | 1085 |
| 1086 if (!PrepareFilter(audio_renderer_)) |
| 1087 return false; |
| 1088 |
| 1089 audio_renderer_->Initialize( |
| 1090 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1091 return true; |
1078 } | 1092 } |
1079 | 1093 |
1080 bool PipelineImpl::InitializeVideoRenderer( | 1094 bool PipelineImpl::InitializeVideoRenderer( |
1081 const scoped_refptr<VideoDecoder>& decoder) { | 1095 const scoped_refptr<VideoDecoder>& decoder) { |
1082 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1096 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1083 DCHECK(IsPipelineOk()); | 1097 DCHECK(IsPipelineOk()); |
1084 | 1098 |
1085 if (decoder) { | 1099 if (!decoder) |
1086 filter_collection_->SelectVideoRenderer(&video_renderer_); | 1100 return false; |
1087 | 1101 |
1088 if (video_renderer_) { | 1102 filter_collection_->SelectVideoRenderer(&video_renderer_); |
1089 PrepareFilter(video_renderer_); | 1103 if (!video_renderer_) { |
1090 video_renderer_->Initialize( | 1104 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1091 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1105 return false; |
1092 return true; | |
1093 } else { | |
1094 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
1095 } | |
1096 } | 1106 } |
1097 return false; | 1107 |
| 1108 if (!PrepareFilter(video_renderer_)) |
| 1109 return false; |
| 1110 |
| 1111 video_renderer_->Initialize( |
| 1112 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1113 return true; |
1098 } | 1114 } |
1099 | 1115 |
1100 scoped_refptr<DemuxerStream> PipelineImpl::FindDemuxerStream( | 1116 scoped_refptr<DemuxerStream> PipelineImpl::FindDemuxerStream( |
1101 const scoped_refptr<Demuxer>& demuxer, | 1117 const scoped_refptr<Demuxer>& demuxer, |
1102 std::string major_mime_type) { | 1118 std::string major_mime_type) { |
1103 DCHECK(demuxer); | 1119 DCHECK(demuxer); |
1104 | 1120 |
1105 const int num_outputs = demuxer->GetNumberOfStreams(); | 1121 const int num_outputs = demuxer->GetNumberOfStreams(); |
1106 for (int i = 0; i < num_outputs; ++i) { | 1122 for (int i = 0; i < num_outputs; ++i) { |
1107 std::string value; | 1123 std::string value; |
(...skipping 30 matching lines...) Expand all Loading... |
1138 this, &PipelineImpl::OnFilterStateTransition)); | 1154 this, &PipelineImpl::OnFilterStateTransition)); |
1139 } | 1155 } |
1140 } else { | 1156 } else { |
1141 state_ = kStopped; | 1157 state_ = kStopped; |
1142 message_loop_->PostTask(FROM_HERE, | 1158 message_loop_->PostTask(FROM_HERE, |
1143 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1159 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
1144 } | 1160 } |
1145 } | 1161 } |
1146 | 1162 |
1147 } // namespace media | 1163 } // namespace media |
OLD | NEW |