OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/logging.h" | 5 #include "base/logging.h" |
6 #include "services/media/factory_service/event.h" | 6 #include "services/media/factory_service/event.h" |
7 #include "services/media/factory_service/media_source_impl.h" | 7 #include "services/media/factory_service/media_source_impl.h" |
8 #include "services/media/framework/conversion_pipeline_builder.h" | 8 #include "services/media/framework/conversion_pipeline_builder.h" |
9 #include "services/media/framework/formatting.h" | 9 #include "services/media/framework/formatting.h" |
10 #include "services/media/framework/parts/reader.h" | 10 #include "services/media/framework/parts/reader.h" |
11 #include "services/media/framework_mojo/mojo_type_conversions.h" | 11 #include "services/media/framework_mojo/mojo_type_conversions.h" |
12 #include "url/gurl.h" | 12 #include "url/gurl.h" |
13 | 13 |
14 namespace mojo { | 14 namespace mojo { |
15 namespace media { | 15 namespace media { |
16 | 16 |
17 // static | 17 // static |
18 std::shared_ptr<MediaSourceImpl> MediaSourceImpl::Create( | 18 std::shared_ptr<MediaSourceImpl> MediaSourceImpl::Create( |
19 const String& origin_url, | 19 const String& origin_url, |
20 const Array<MediaTypeSetPtr>& allowed_media_types, | 20 const Array<MediaTypeSetPtr>& allowed_media_types, |
21 InterfaceRequest<MediaSource> request, | 21 InterfaceRequest<MediaSource> request, |
22 MediaFactoryService* owner) { | 22 MediaFactoryService* owner) { |
23 return std::shared_ptr<MediaSourceImpl>(new MediaSourceImpl( | 23 return std::shared_ptr<MediaSourceImpl>(new MediaSourceImpl( |
24 origin_url, | 24 origin_url, allowed_media_types, request.Pass(), owner)); |
25 allowed_media_types, | |
26 request.Pass(), | |
27 owner)); | |
28 } | 25 } |
29 | 26 |
30 MediaSourceImpl::MediaSourceImpl( | 27 MediaSourceImpl::MediaSourceImpl( |
31 const String& origin_url, | 28 const String& origin_url, |
32 const Array<MediaTypeSetPtr>& allowed_media_types, | 29 const Array<MediaTypeSetPtr>& allowed_media_types, |
33 InterfaceRequest<MediaSource> request, | 30 InterfaceRequest<MediaSource> request, |
34 MediaFactoryService* owner) | 31 MediaFactoryService* owner) |
35 : MediaFactoryService::Product(owner), | 32 : MediaFactoryService::Product(owner), binding_(this, request.Pass()) { |
36 binding_(this, request.Pass()) { | |
37 DCHECK(origin_url); | 33 DCHECK(origin_url); |
38 | 34 |
39 // Go away when the client is no longer connected. | 35 // Go away when the client is no longer connected. |
40 binding_.set_connection_error_handler([this]() { | 36 binding_.set_connection_error_handler([this]() { ReleaseFromOwner(); }); |
41 ReleaseFromOwner(); | |
42 }); | |
43 | 37 |
44 GURL gurl = GURL(origin_url); | 38 GURL gurl = GURL(origin_url); |
45 | 39 |
46 // TODO(dalesat): Support mojo urls for capture scenarios. | 40 // TODO(dalesat): Support mojo urls for capture scenarios. |
47 | 41 |
48 Result result = Reader::Create(gurl, &reader_); | 42 Result result = Reader::Create(gurl, &reader_); |
49 if (result != Result::kOk) { | 43 if (result != Result::kOk) { |
50 NOTREACHED() << "couldn't create reader: " << result; | 44 NOTREACHED() << "couldn't create reader: " << result; |
51 state_ = MediaState::FAULT; | 45 state_ = MediaState::FAULT; |
52 return; | 46 return; |
53 } | 47 } |
54 | 48 |
55 result = Demux::Create(reader_, &demux_); | 49 result = Demux::Create(reader_, &demux_); |
56 if (result != Result::kOk) { | 50 if (result != Result::kOk) { |
57 NOTREACHED() << "couldn't create demux: " << result; | 51 NOTREACHED() << "couldn't create demux: " << result; |
58 state_ = MediaState::FAULT; | 52 state_ = MediaState::FAULT; |
59 return; | 53 return; |
60 } | 54 } |
61 | 55 |
62 demux_part_ = graph_.Add(demux_); | 56 demux_part_ = graph_.Add(demux_); |
63 | 57 |
64 auto demux_streams = demux_->streams(); | 58 auto demux_streams = demux_->streams(); |
65 for (auto demux_stream : demux_streams) { | 59 for (auto demux_stream : demux_streams) { |
66 streams_.push_back(std::unique_ptr<Stream>(new Stream( | 60 streams_.push_back(std::unique_ptr<Stream>(new Stream( |
67 demux_part_.output(demux_stream->index()), | 61 demux_part_.output(demux_stream->index()), demux_stream->stream_type(), |
68 demux_stream->stream_type(), | 62 Convert(allowed_media_types), &graph_))); |
69 Convert(allowed_media_types), | |
70 &graph_))); | |
71 } | 63 } |
72 } | 64 } |
73 | 65 |
74 MediaSourceImpl::~MediaSourceImpl() {} | 66 MediaSourceImpl::~MediaSourceImpl() {} |
75 | 67 |
76 void MediaSourceImpl::GetStreams(const GetStreamsCallback& callback) { | 68 void MediaSourceImpl::GetStreams(const GetStreamsCallback& callback) { |
77 auto result = Array<MediaSourceStreamDescriptorPtr>::New(streams_.size()); | 69 auto result = Array<MediaSourceStreamDescriptorPtr>::New(streams_.size()); |
78 for (size_t i = 0; i < streams_.size(); i++) { | 70 for (size_t i = 0; i < streams_.size(); i++) { |
79 MediaSourceStreamDescriptorPtr descriptor = | 71 MediaSourceStreamDescriptorPtr descriptor = |
80 MediaSourceStreamDescriptor::New(); | 72 MediaSourceStreamDescriptor::New(); |
(...skipping 12 matching lines...) Expand all Loading... |
93 } | 85 } |
94 | 86 |
95 void MediaSourceImpl::GetMasterClock(InterfaceRequest<Clock> master_clock) { | 87 void MediaSourceImpl::GetMasterClock(InterfaceRequest<Clock> master_clock) { |
96 // TODO(dalesat): Produce master clock as appropriate. | 88 // TODO(dalesat): Produce master clock as appropriate. |
97 } | 89 } |
98 | 90 |
99 void MediaSourceImpl::SetMasterClock(InterfaceHandle<Clock> master_clock) { | 91 void MediaSourceImpl::SetMasterClock(InterfaceHandle<Clock> master_clock) { |
100 // TODO(dalesat): Is this needed? | 92 // TODO(dalesat): Is this needed? |
101 } | 93 } |
102 | 94 |
103 void MediaSourceImpl::GetProducer( | 95 void MediaSourceImpl::GetProducer(uint32_t stream_index, |
104 uint32_t stream_index, | 96 InterfaceRequest<MediaProducer> producer) { |
105 InterfaceRequest<MediaProducer> producer) { | |
106 if (stream_index >= streams_.size()) { | 97 if (stream_index >= streams_.size()) { |
107 return; | 98 return; |
108 } | 99 } |
109 | 100 |
110 streams_[stream_index]->GetProducer(producer.Pass()); | 101 streams_[stream_index]->GetProducer(producer.Pass()); |
111 } | 102 } |
112 | 103 |
113 void MediaSourceImpl::GetPullModeProducer( | 104 void MediaSourceImpl::GetPullModeProducer( |
114 uint32_t stream_index, | 105 uint32_t stream_index, |
115 InterfaceRequest<MediaPullModeProducer> producer) { | 106 InterfaceRequest<MediaPullModeProducer> producer) { |
116 if (stream_index >= streams_.size()) { | 107 if (stream_index >= streams_.size()) { |
117 return; | 108 return; |
118 } | 109 } |
119 | 110 |
120 streams_[stream_index]->GetPullModeProducer(producer.Pass()); | 111 streams_[stream_index]->GetPullModeProducer(producer.Pass()); |
121 } | 112 } |
122 | 113 |
123 void MediaSourceImpl::GetStatus( | 114 void MediaSourceImpl::GetStatus(uint64_t version_last_seen, |
124 uint64_t version_last_seen, | 115 const GetStatusCallback& callback) { |
125 const GetStatusCallback& callback) { | |
126 if (version_last_seen < status_version_) { | 116 if (version_last_seen < status_version_) { |
127 RunStatusCallback(callback); | 117 RunStatusCallback(callback); |
128 } else { | 118 } else { |
129 pending_status_requests_.push_back(callback); | 119 pending_status_requests_.push_back(callback); |
130 } | 120 } |
131 } | 121 } |
132 | 122 |
133 void MediaSourceImpl::Prepare(const PrepareCallback& callback) { | 123 void MediaSourceImpl::Prepare(const PrepareCallback& callback) { |
134 for (auto& stream : streams_) { | 124 for (auto& stream : streams_) { |
135 stream->EnsureSink(); | 125 stream->EnsureSink(); |
136 } | 126 } |
137 graph_.Prepare(); | 127 graph_.Prepare(); |
138 state_ = MediaState::PAUSED; | 128 state_ = MediaState::PAUSED; |
139 callback.Run(); | 129 callback.Run(); |
140 StatusUpdated(); | 130 StatusUpdated(); |
141 } | 131 } |
142 | 132 |
143 void MediaSourceImpl::Prime(const PrimeCallback& callback) { | 133 void MediaSourceImpl::Prime(const PrimeCallback& callback) { |
144 std::vector<Event> stream_primed_events; | 134 std::vector<Event> stream_primed_events; |
145 | 135 |
146 for (auto& stream : streams_) { | 136 for (auto& stream : streams_) { |
147 Event stream_primed = Event::Create(); | 137 Event stream_primed = Event::Create(); |
148 stream_primed_events.push_back(stream_primed); | 138 stream_primed_events.push_back(stream_primed); |
149 stream->PrimeConnection(stream_primed); | 139 stream->PrimeConnection(stream_primed); |
150 } | 140 } |
151 | 141 |
152 Event all_streams_primed = Event::All(stream_primed_events); | 142 Event all_streams_primed = Event::All(stream_primed_events); |
153 | 143 |
154 // Capture all_streams_primed so it doesn't get deleted before it occurs. | 144 // Capture all_streams_primed so it doesn't get deleted before it occurs. |
155 all_streams_primed.When([callback, all_streams_primed]() { | 145 all_streams_primed.When([callback, all_streams_primed]() { callback.Run(); }); |
156 callback.Run(); | |
157 }); | |
158 } | 146 } |
159 | 147 |
160 void MediaSourceImpl::Flush(const FlushCallback& callback) { | 148 void MediaSourceImpl::Flush(const FlushCallback& callback) { |
161 graph_.FlushAllOutputs(demux_part_); | 149 graph_.FlushAllOutputs(demux_part_); |
162 | 150 |
163 std::vector<Event> stream_flushed_events; | 151 std::vector<Event> stream_flushed_events; |
164 | 152 |
165 for (auto& stream : streams_) { | 153 for (auto& stream : streams_) { |
166 Event stream_flushed = Event::Create(); | 154 Event stream_flushed = Event::Create(); |
167 stream_flushed_events.push_back(stream_flushed); | 155 stream_flushed_events.push_back(stream_flushed); |
168 stream->FlushConnection(stream_flushed); | 156 stream->FlushConnection(stream_flushed); |
169 } | 157 } |
170 | 158 |
171 Event all_streams_flushed = Event::All(stream_flushed_events); | 159 Event all_streams_flushed = Event::All(stream_flushed_events); |
172 | 160 |
173 // Capture all_streams_flushed so it doesn't get deleted before it occurs. | 161 // Capture all_streams_flushed so it doesn't get deleted before it occurs. |
174 all_streams_flushed.When([callback, all_streams_flushed]() { | 162 all_streams_flushed.When( |
175 callback.Run(); | 163 [callback, all_streams_flushed]() { callback.Run(); }); |
176 }); | |
177 } | 164 } |
178 | 165 |
179 void MediaSourceImpl::Seek(int64_t position, const FlushCallback& callback) { | 166 void MediaSourceImpl::Seek(int64_t position, const FlushCallback& callback) { |
180 demux_->Seek(position); | 167 demux_->Seek(position); |
181 callback.Run(); | 168 callback.Run(); |
182 } | 169 } |
183 | 170 |
184 void MediaSourceImpl::StatusUpdated() { | 171 void MediaSourceImpl::StatusUpdated() { |
185 ++status_version_; | 172 ++status_version_; |
186 while (!pending_status_requests_.empty()) { | 173 while (!pending_status_requests_.empty()) { |
187 RunStatusCallback(pending_status_requests_.front()); | 174 RunStatusCallback(pending_status_requests_.front()); |
188 pending_status_requests_.pop_front(); | 175 pending_status_requests_.pop_front(); |
189 } | 176 } |
190 } | 177 } |
191 | 178 |
192 void MediaSourceImpl::RunStatusCallback(const GetStatusCallback& callback) | 179 void MediaSourceImpl::RunStatusCallback( |
193 const { | 180 const GetStatusCallback& callback) const { |
194 MediaSourceStatusPtr status = MediaSourceStatus::New(); | 181 MediaSourceStatusPtr status = MediaSourceStatus::New(); |
195 status->state = state_; | 182 status->state = state_; |
196 status->metadata = demux_ ? Convert(demux_->metadata()) : nullptr; | 183 status->metadata = demux_ ? Convert(demux_->metadata()) : nullptr; |
197 callback.Run(status_version_, status.Pass()); | 184 callback.Run(status_version_, status.Pass()); |
198 } | 185 } |
199 | 186 |
200 MediaSourceImpl::Stream::Stream( | 187 MediaSourceImpl::Stream::Stream( |
201 OutputRef output, | 188 OutputRef output, |
202 std::unique_ptr<StreamType> stream_type, | 189 std::unique_ptr<StreamType> stream_type, |
203 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& | 190 const std::unique_ptr<std::vector<std::unique_ptr<StreamTypeSet>>>& |
204 allowed_stream_types, | 191 allowed_stream_types, |
205 Graph* graph) : | 192 Graph* graph) |
206 original_stream_type_(std::move(stream_type)), | 193 : original_stream_type_(std::move(stream_type)), graph_(graph) { |
207 graph_(graph) { | |
208 DCHECK(original_stream_type_); | 194 DCHECK(original_stream_type_); |
209 DCHECK(graph); | 195 DCHECK(graph); |
210 | 196 |
211 output_ = output; | 197 output_ = output; |
212 | 198 |
213 if (allowed_stream_types == nullptr) { | 199 if (allowed_stream_types == nullptr) { |
214 // No conversion requested. | 200 // No conversion requested. |
215 stream_type_ = SafeClone(original_stream_type_); | 201 stream_type_ = SafeClone(original_stream_type_); |
216 } else if (!BuildConversionPipeline( | 202 } else if (!BuildConversionPipeline(*original_stream_type_, |
217 *original_stream_type_, | 203 *allowed_stream_types, graph, &output_, |
218 *allowed_stream_types, | 204 &stream_type_)) { |
219 graph, | |
220 &output_, | |
221 &stream_type_)) { | |
222 // Can't convert to any allowed type. | 205 // Can't convert to any allowed type. |
223 stream_type_ = StreamType::Create(StreamType::Scheme::kNone); | 206 stream_type_ = StreamType::Create(StreamType::Scheme::kNone); |
224 } | 207 } |
225 } | 208 } |
226 | 209 |
227 MediaSourceImpl::Stream::~Stream() {} | 210 MediaSourceImpl::Stream::~Stream() {} |
228 | 211 |
229 MediaTypePtr MediaSourceImpl::Stream::media_type() const { | 212 MediaTypePtr MediaSourceImpl::Stream::media_type() const { |
230 return Convert(stream_type_); | 213 return Convert(stream_type_); |
231 } | 214 } |
(...skipping 26 matching lines...) Expand all Loading... |
258 | 241 |
259 if (!pull_mode_producer_) { | 242 if (!pull_mode_producer_) { |
260 pull_mode_producer_ = MojoPullModeProducer::Create(); | 243 pull_mode_producer_ = MojoPullModeProducer::Create(); |
261 graph_->ConnectOutputToPart(output_, graph_->Add(pull_mode_producer_)); | 244 graph_->ConnectOutputToPart(output_, graph_->Add(pull_mode_producer_)); |
262 } | 245 } |
263 | 246 |
264 pull_mode_producer_->AddBinding(producer.Pass()); | 247 pull_mode_producer_->AddBinding(producer.Pass()); |
265 } | 248 } |
266 | 249 |
267 void MediaSourceImpl::Stream::EnsureSink() { | 250 void MediaSourceImpl::Stream::EnsureSink() { |
268 if (producer_ == nullptr && pull_mode_producer_ == nullptr) { | 251 if (producer_ == nullptr && pull_mode_producer_ == nullptr) { |
269 null_sink_ = NullSink::Create(); | 252 null_sink_ = NullSink::Create(); |
270 graph_->ConnectOutputToPart(output_, graph_->Add(null_sink_)); | 253 graph_->ConnectOutputToPart(output_, graph_->Add(null_sink_)); |
271 } | 254 } |
272 } | 255 } |
273 | 256 |
274 void MediaSourceImpl::Stream::PrimeConnection( | 257 void MediaSourceImpl::Stream::PrimeConnection( |
275 const MojoProducer::PrimeConnectionCallback callback) { | 258 const MojoProducer::PrimeConnectionCallback callback) { |
276 if (producer_ != nullptr) { | 259 if (producer_ != nullptr) { |
277 producer_->PrimeConnection(callback); | 260 producer_->PrimeConnection(callback); |
278 } | 261 } |
279 } | 262 } |
280 | 263 |
281 void MediaSourceImpl::Stream::FlushConnection( | 264 void MediaSourceImpl::Stream::FlushConnection( |
282 const MojoProducer::FlushConnectionCallback callback) { | 265 const MojoProducer::FlushConnectionCallback callback) { |
283 if (producer_ != nullptr) { | 266 if (producer_ != nullptr) { |
284 producer_->FlushConnection(callback); | 267 producer_->FlushConnection(callback); |
285 } | 268 } |
286 } | 269 } |
287 | 270 |
288 } // namespace media | 271 } // namespace media |
289 } // namespace mojo | 272 } // namespace mojo |
OLD | NEW |