| 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 |