| 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 |
| 981 pipeline_init_state_->data_source_ = data_source; | 984 pipeline_init_state_->data_source_ = data_source; |
| 982 data_source->Initialize( | 985 data_source->Initialize( |
| 983 url_, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 986 url_, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 984 } | 987 } |
| 985 | 988 |
| 986 void PipelineImpl::InitializeDemuxer( | 989 void PipelineImpl::InitializeDemuxer( |
| 987 const scoped_refptr<DataSource>& data_source) { | 990 const scoped_refptr<DataSource>& data_source) { |
| 988 DCHECK_EQ(MessageLoop::current(), message_loop_); | 991 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 989 DCHECK(IsPipelineOk()); | 992 DCHECK(IsPipelineOk()); |
| 990 | 993 |
| 991 scoped_refptr<Demuxer> demuxer; | 994 scoped_refptr<Demuxer> demuxer; |
| 992 | 995 |
| 993 CHECK(data_source); | 996 CHECK(data_source); |
| 994 | 997 |
| 995 filter_collection_->SelectDemuxer(&demuxer); | 998 filter_collection_->SelectDemuxer(&demuxer); |
| 996 if (!demuxer) { | 999 if (!demuxer) { |
| 997 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1000 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 998 return; | 1001 return; |
| 999 } | 1002 } |
| 1000 | 1003 |
| 1001 PrepareFilter(demuxer); | 1004 if (!PrepareFilter(demuxer)) |
| 1005 return; |
| 1006 |
| 1002 pipeline_init_state_->demuxer_ = demuxer; | 1007 pipeline_init_state_->demuxer_ = demuxer; |
| 1003 demuxer->Initialize(data_source, | 1008 demuxer->Initialize(data_source, |
| 1004 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1009 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1005 } | 1010 } |
| 1006 | 1011 |
| 1007 bool PipelineImpl::InitializeAudioDecoder( | 1012 bool PipelineImpl::InitializeAudioDecoder( |
| 1008 const scoped_refptr<Demuxer>& demuxer) { | 1013 const scoped_refptr<Demuxer>& demuxer) { |
| 1009 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1014 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1010 DCHECK(IsPipelineOk()); | 1015 DCHECK(IsPipelineOk()); |
| 1011 | 1016 |
| 1012 scoped_refptr<DemuxerStream> stream = | 1017 scoped_refptr<DemuxerStream> stream = |
| 1013 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); | 1018 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); |
| 1014 | 1019 |
| 1015 if (stream) { | 1020 if (!stream) |
| 1016 scoped_refptr<AudioDecoder> audio_decoder; | 1021 return false; |
| 1017 filter_collection_->SelectAudioDecoder(&audio_decoder); | |
| 1018 | 1022 |
| 1019 if (audio_decoder) { | 1023 scoped_refptr<AudioDecoder> audio_decoder; |
| 1020 PrepareFilter(audio_decoder); | 1024 filter_collection_->SelectAudioDecoder(&audio_decoder); |
| 1021 pipeline_init_state_->audio_decoder_ = audio_decoder; | 1025 |
| 1022 audio_decoder->Initialize( | 1026 if (!audio_decoder) { |
| 1023 stream, | 1027 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 1024 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1028 return false; |
| 1025 return true; | |
| 1026 } else { | |
| 1027 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
| 1028 } | |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 return false; | 1031 if (!PrepareFilter(audio_decoder)) |
| 1032 return false; |
| 1033 |
| 1034 pipeline_init_state_->audio_decoder_ = audio_decoder; |
| 1035 audio_decoder->Initialize( |
| 1036 stream, |
| 1037 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1038 return true; |
| 1032 } | 1039 } |
| 1033 | 1040 |
| 1034 bool PipelineImpl::InitializeVideoDecoder( | 1041 bool PipelineImpl::InitializeVideoDecoder( |
| 1035 const scoped_refptr<Demuxer>& demuxer) { | 1042 const scoped_refptr<Demuxer>& demuxer) { |
| 1036 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1043 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1037 DCHECK(IsPipelineOk()); | 1044 DCHECK(IsPipelineOk()); |
| 1038 | 1045 |
| 1039 scoped_refptr<DemuxerStream> stream = | 1046 scoped_refptr<DemuxerStream> stream = |
| 1040 FindDemuxerStream(demuxer, mime_type::kMajorTypeVideo); | 1047 FindDemuxerStream(demuxer, mime_type::kMajorTypeVideo); |
| 1041 | 1048 |
| 1042 if (stream) { | 1049 if (!stream) |
| 1043 scoped_refptr<VideoDecoder> video_decoder; | 1050 return false; |
| 1044 filter_collection_->SelectVideoDecoder(&video_decoder); | |
| 1045 | 1051 |
| 1046 if (video_decoder) { | 1052 scoped_refptr<VideoDecoder> video_decoder; |
| 1047 PrepareFilter(video_decoder); | 1053 filter_collection_->SelectVideoDecoder(&video_decoder); |
| 1048 pipeline_init_state_->video_decoder_ = video_decoder; | 1054 |
| 1049 video_decoder->Initialize( | 1055 if (!video_decoder) { |
| 1050 stream, | 1056 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 1051 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1057 return false; |
| 1052 return true; | |
| 1053 } else { | |
| 1054 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
| 1055 } | |
| 1056 } | 1058 } |
| 1057 return false; | 1059 |
| 1060 if (!PrepareFilter(video_decoder)) |
| 1061 return false; |
| 1062 |
| 1063 pipeline_init_state_->video_decoder_ = video_decoder; |
| 1064 video_decoder->Initialize( |
| 1065 stream, |
| 1066 NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1067 return true; |
| 1058 } | 1068 } |
| 1059 | 1069 |
| 1060 bool PipelineImpl::InitializeAudioRenderer( | 1070 bool PipelineImpl::InitializeAudioRenderer( |
| 1061 const scoped_refptr<AudioDecoder>& decoder) { | 1071 const scoped_refptr<AudioDecoder>& decoder) { |
| 1062 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1072 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1063 DCHECK(IsPipelineOk()); | 1073 DCHECK(IsPipelineOk()); |
| 1064 | 1074 |
| 1065 if (decoder) { | 1075 if (!decoder) |
| 1066 filter_collection_->SelectAudioRenderer(&audio_renderer_); | 1076 return false; |
| 1067 | 1077 |
| 1068 if (audio_renderer_) { | 1078 filter_collection_->SelectAudioRenderer(&audio_renderer_); |
| 1069 PrepareFilter(audio_renderer_); | 1079 if (!audio_renderer_) { |
| 1070 audio_renderer_->Initialize( | 1080 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 1071 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1081 return false; |
| 1072 return true; | |
| 1073 } else { | |
| 1074 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
| 1075 } | |
| 1076 } | 1082 } |
| 1077 return false; | 1083 |
| 1084 if (!PrepareFilter(audio_renderer_)) |
| 1085 return false; |
| 1086 |
| 1087 audio_renderer_->Initialize( |
| 1088 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1089 return true; |
| 1078 } | 1090 } |
| 1079 | 1091 |
| 1080 bool PipelineImpl::InitializeVideoRenderer( | 1092 bool PipelineImpl::InitializeVideoRenderer( |
| 1081 const scoped_refptr<VideoDecoder>& decoder) { | 1093 const scoped_refptr<VideoDecoder>& decoder) { |
| 1082 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1094 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1083 DCHECK(IsPipelineOk()); | 1095 DCHECK(IsPipelineOk()); |
| 1084 | 1096 |
| 1085 if (decoder) { | 1097 if (!decoder) |
| 1086 filter_collection_->SelectVideoRenderer(&video_renderer_); | 1098 return false; |
| 1087 | 1099 |
| 1088 if (video_renderer_) { | 1100 filter_collection_->SelectVideoRenderer(&video_renderer_); |
| 1089 PrepareFilter(video_renderer_); | 1101 if (!video_renderer_) { |
| 1090 video_renderer_->Initialize( | 1102 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 1091 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); | 1103 return false; |
| 1092 return true; | |
| 1093 } else { | |
| 1094 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | |
| 1095 } | |
| 1096 } | 1104 } |
| 1097 return false; | 1105 |
| 1106 if (!PrepareFilter(video_renderer_)) |
| 1107 return false; |
| 1108 |
| 1109 video_renderer_->Initialize( |
| 1110 decoder, NewCallback(this, &PipelineImpl::OnFilterInitialize)); |
| 1111 return true; |
| 1098 } | 1112 } |
| 1099 | 1113 |
| 1100 scoped_refptr<DemuxerStream> PipelineImpl::FindDemuxerStream( | 1114 scoped_refptr<DemuxerStream> PipelineImpl::FindDemuxerStream( |
| 1101 const scoped_refptr<Demuxer>& demuxer, | 1115 const scoped_refptr<Demuxer>& demuxer, |
| 1102 std::string major_mime_type) { | 1116 std::string major_mime_type) { |
| 1103 DCHECK(demuxer); | 1117 DCHECK(demuxer); |
| 1104 | 1118 |
| 1105 const int num_outputs = demuxer->GetNumberOfStreams(); | 1119 const int num_outputs = demuxer->GetNumberOfStreams(); |
| 1106 for (int i = 0; i < num_outputs; ++i) { | 1120 for (int i = 0; i < num_outputs; ++i) { |
| 1107 std::string value; | 1121 std::string value; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1138 this, &PipelineImpl::OnFilterStateTransition)); | 1152 this, &PipelineImpl::OnFilterStateTransition)); |
| 1139 } | 1153 } |
| 1140 } else { | 1154 } else { |
| 1141 state_ = kStopped; | 1155 state_ = kStopped; |
| 1142 message_loop_->PostTask(FROM_HERE, | 1156 message_loop_->PostTask(FROM_HERE, |
| 1143 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1157 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
| 1144 } | 1158 } |
| 1145 } | 1159 } |
| 1146 | 1160 |
| 1147 } // namespace media | 1161 } // namespace media |
| OLD | NEW |