| 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 "mojo/public/cpp/application/connect.h" | 6 #include "mojo/public/cpp/application/connect.h" |
| 7 #include "mojo/services/media/common/cpp/timeline.h" | 7 #include "mojo/services/media/common/cpp/timeline.h" |
| 8 #include "services/media/factory_service/media_player_impl.h" | 8 #include "services/media/factory_service/media_player_impl.h" |
| 9 #include "services/media/framework/parts/reader.h" | 9 #include "services/media/framework/parts/reader.h" |
| 10 #include "services/media/framework/util/callback_joiner.h" | 10 #include "services/media/framework/util/callback_joiner.h" |
| 11 | 11 |
| 12 namespace mojo { | 12 namespace mojo { |
| 13 namespace media { | 13 namespace media { |
| 14 | 14 |
| 15 // static | 15 // static |
| 16 std::shared_ptr<MediaPlayerImpl> MediaPlayerImpl::Create( | 16 std::shared_ptr<MediaPlayerImpl> MediaPlayerImpl::Create( |
| 17 InterfaceHandle<SeekingReader> reader, | 17 InterfaceHandle<SeekingReader> reader, |
| 18 InterfaceHandle<MediaRenderer> audio_renderer, |
| 19 InterfaceHandle<MediaRenderer> video_renderer, |
| 18 InterfaceRequest<MediaPlayer> request, | 20 InterfaceRequest<MediaPlayer> request, |
| 19 MediaFactoryService* owner) { | 21 MediaFactoryService* owner) { |
| 20 return std::shared_ptr<MediaPlayerImpl>( | 22 return std::shared_ptr<MediaPlayerImpl>( |
| 21 new MediaPlayerImpl(reader.Pass(), request.Pass(), owner)); | 23 new MediaPlayerImpl(reader.Pass(), audio_renderer.Pass(), |
| 24 video_renderer.Pass(), request.Pass(), owner)); |
| 22 } | 25 } |
| 23 | 26 |
| 24 MediaPlayerImpl::MediaPlayerImpl(InterfaceHandle<SeekingReader> reader, | 27 MediaPlayerImpl::MediaPlayerImpl(InterfaceHandle<SeekingReader> reader, |
| 28 InterfaceHandle<MediaRenderer> audio_renderer, |
| 29 InterfaceHandle<MediaRenderer> video_renderer, |
| 25 InterfaceRequest<MediaPlayer> request, | 30 InterfaceRequest<MediaPlayer> request, |
| 26 MediaFactoryService* owner) | 31 MediaFactoryService* owner) |
| 27 : MediaFactoryService::Product<MediaPlayer>(this, request.Pass(), owner) { | 32 : MediaFactoryService::Product<MediaPlayer>(this, request.Pass(), owner) { |
| 28 DCHECK(reader); | 33 DCHECK(reader); |
| 29 | 34 |
| 30 status_publisher_.SetCallbackRunner([this](const GetStatusCallback& callback, | 35 status_publisher_.SetCallbackRunner([this](const GetStatusCallback& callback, |
| 31 uint64_t version) { | 36 uint64_t version) { |
| 32 MediaPlayerStatusPtr status = MediaPlayerStatus::New(); | 37 MediaPlayerStatusPtr status = MediaPlayerStatus::New(); |
| 33 status->timeline_transform = TimelineTransform::From(timeline_function_); | 38 status->timeline_transform = TimelineTransform::From(timeline_function_); |
| 34 status->end_of_stream = end_of_stream_; | 39 status->end_of_stream = end_of_stream_; |
| 35 status->metadata = metadata_.Clone(); | 40 status->metadata = metadata_.Clone(); |
| 36 callback.Run(version, status.Pass()); | 41 callback.Run(version, status.Pass()); |
| 37 }); | 42 }); |
| 38 | 43 |
| 39 state_ = State::kWaiting; | 44 state_ = State::kWaiting; |
| 40 | 45 |
| 41 ConnectToService(owner->shell(), "mojo:media_factory", GetProxy(&factory_)); | 46 ConnectToService(owner->shell(), "mojo:media_factory", GetProxy(&factory_)); |
| 42 | 47 |
| 43 factory_->CreateDemux(reader.Pass(), GetProxy(&demux_)); | 48 factory_->CreateDemux(reader.Pass(), GetProxy(&demux_)); |
| 44 HandleDemuxMetadataUpdates(); | 49 HandleDemuxMetadataUpdates(); |
| 45 | 50 |
| 46 factory_->CreateTimelineController(GetProxy(&timeline_controller_)); | 51 factory_->CreateTimelineController(GetProxy(&timeline_controller_)); |
| 47 timeline_controller_->GetControlSite(GetProxy(&timeline_control_site_)); | 52 timeline_controller_->GetControlSite(GetProxy(&timeline_control_site_)); |
| 48 timeline_control_site_->GetTimelineConsumer(GetProxy(&timeline_consumer_)); | 53 timeline_control_site_->GetTimelineConsumer(GetProxy(&timeline_consumer_)); |
| 49 HandleTimelineControlSiteStatusUpdates(); | 54 HandleTimelineControlSiteStatusUpdates(); |
| 50 | 55 |
| 56 audio_renderer_ = audio_renderer.Pass(); |
| 57 video_renderer_ = video_renderer.Pass(); |
| 58 |
| 51 demux_->Describe([this](mojo::Array<MediaTypePtr> stream_types) { | 59 demux_->Describe([this](mojo::Array<MediaTypePtr> stream_types) { |
| 52 // Populate streams_ and enable the streams we want. | 60 // Populate streams_ and enable the streams we want. |
| 53 std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); | 61 std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); |
| 54 | 62 |
| 55 for (MediaTypePtr& stream_type : stream_types) { | 63 for (MediaTypePtr& stream_type : stream_types) { |
| 56 streams_.push_back(std::unique_ptr<Stream>(new Stream())); | 64 streams_.push_back(std::unique_ptr<Stream>(new Stream())); |
| 57 Stream& stream = *streams_.back(); | 65 Stream& stream = *streams_.back(); |
| 58 switch (stream_type->medium) { | 66 switch (stream_type->medium) { |
| 59 case MediaTypeMedium::AUDIO: | 67 case MediaTypeMedium::AUDIO: |
| 68 stream.renderer_ = audio_renderer_.Pass(); |
| 60 PrepareStream(&stream, streams_.size() - 1, stream_type, | 69 PrepareStream(&stream, streams_.size() - 1, stream_type, |
| 61 "mojo:audio_server", callback_joiner->NewCallback()); | 70 callback_joiner->NewCallback()); |
| 62 break; | 71 break; |
| 63 case MediaTypeMedium::VIDEO: | 72 case MediaTypeMedium::VIDEO: |
| 64 // TODO(dalesat): Send video somewhere. | 73 stream.renderer_ = video_renderer_.Pass(); |
| 65 PrepareStream(&stream, streams_.size() - 1, stream_type, "nowhere", | 74 PrepareStream(&stream, streams_.size() - 1, stream_type, |
| 66 callback_joiner->NewCallback()); | 75 callback_joiner->NewCallback()); |
| 67 break; | 76 break; |
| 68 // TODO(dalesat): Enable other stream types. | 77 // TODO(dalesat): Enable other stream types. |
| 69 default: | 78 default: |
| 70 break; | 79 break; |
| 71 } | 80 } |
| 72 } | 81 } |
| 73 | 82 |
| 74 callback_joiner->WhenJoined([this]() { | 83 callback_joiner->WhenJoined([this]() { |
| 75 // The enabled streams are prepared. | 84 // The enabled streams are prepared. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 } | 195 } |
| 187 | 196 |
| 188 void MediaPlayerImpl::Seek(int64_t position) { | 197 void MediaPlayerImpl::Seek(int64_t position) { |
| 189 target_position_ = position; | 198 target_position_ = position; |
| 190 Update(); | 199 Update(); |
| 191 } | 200 } |
| 192 | 201 |
| 193 void MediaPlayerImpl::PrepareStream(Stream* stream, | 202 void MediaPlayerImpl::PrepareStream(Stream* stream, |
| 194 size_t index, | 203 size_t index, |
| 195 const MediaTypePtr& input_media_type, | 204 const MediaTypePtr& input_media_type, |
| 196 const String& url, | |
| 197 const std::function<void()>& callback) { | 205 const std::function<void()>& callback) { |
| 198 DCHECK(factory_); | 206 DCHECK(factory_); |
| 199 | 207 |
| 200 demux_->GetProducer(index, GetProxy(&stream->encoded_producer_)); | 208 demux_->GetProducer(index, GetProxy(&stream->encoded_producer_)); |
| 201 | 209 |
| 202 if (input_media_type->encoding != MediaType::kAudioEncodingLpcm && | 210 if (input_media_type->encoding != MediaType::kAudioEncodingLpcm && |
| 203 input_media_type->encoding != MediaType::kVideoEncodingUncompressed) { | 211 input_media_type->encoding != MediaType::kVideoEncodingUncompressed) { |
| 204 std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); | 212 std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); |
| 205 | 213 |
| 206 // Compressed media. Insert a decoder in front of the sink. The sink would | 214 // Compressed media. Insert a decoder in front of the sink. The sink would |
| 207 // add its own internal decoder, but we want to test the decoder. | 215 // add its own internal decoder, but we want to test the decoder. |
| 208 factory_->CreateDecoder(input_media_type.Clone(), | 216 factory_->CreateDecoder(input_media_type.Clone(), |
| 209 GetProxy(&stream->decoder_)); | 217 GetProxy(&stream->decoder_)); |
| 210 | 218 |
| 211 MediaConsumerPtr decoder_consumer; | 219 MediaConsumerPtr decoder_consumer; |
| 212 stream->decoder_->GetConsumer(GetProxy(&decoder_consumer)); | 220 stream->decoder_->GetConsumer(GetProxy(&decoder_consumer)); |
| 213 | 221 |
| 214 callback_joiner->Spawn(); | 222 callback_joiner->Spawn(); |
| 215 stream->encoded_producer_->Connect(decoder_consumer.Pass(), | 223 stream->encoded_producer_->Connect(decoder_consumer.Pass(), |
| 216 [stream, callback_joiner]() { | 224 [stream, callback_joiner]() { |
| 217 stream->encoded_producer_.reset(); | 225 stream->encoded_producer_.reset(); |
| 218 callback_joiner->Complete(); | 226 callback_joiner->Complete(); |
| 219 }); | 227 }); |
| 220 | 228 |
| 221 callback_joiner->Spawn(); | 229 callback_joiner->Spawn(); |
| 222 stream->decoder_->GetOutputType( | 230 stream->decoder_->GetOutputType( |
| 223 [this, stream, url, callback_joiner](MediaTypePtr output_type) { | 231 [this, stream, callback_joiner](MediaTypePtr output_type) { |
| 224 stream->decoder_->GetProducer(GetProxy(&stream->decoded_producer_)); | 232 stream->decoder_->GetProducer(GetProxy(&stream->decoded_producer_)); |
| 225 CreateSink(stream, output_type, url, callback_joiner->NewCallback()); | 233 CreateSink(stream, output_type, callback_joiner->NewCallback()); |
| 226 callback_joiner->Complete(); | 234 callback_joiner->Complete(); |
| 227 }); | 235 }); |
| 228 | 236 |
| 229 callback_joiner->WhenJoined(callback); | 237 callback_joiner->WhenJoined(callback); |
| 230 } else { | 238 } else { |
| 231 // Uncompressed media. Connect the demux stream directly to the sink. This | 239 // Uncompressed media. Connect the demux stream directly to the sink. This |
| 232 // would work for compressed media as well (the sink would decode), but we | 240 // would work for compressed media as well (the sink would decode), but we |
| 233 // want to test the decoder. | 241 // want to test the decoder. |
| 234 stream->decoded_producer_ = stream->encoded_producer_.Pass(); | 242 stream->decoded_producer_ = stream->encoded_producer_.Pass(); |
| 235 CreateSink(stream, input_media_type, url, callback); | 243 CreateSink(stream, input_media_type, callback); |
| 236 } | 244 } |
| 237 } | 245 } |
| 238 | 246 |
| 239 void MediaPlayerImpl::CreateSink(Stream* stream, | 247 void MediaPlayerImpl::CreateSink(Stream* stream, |
| 240 const MediaTypePtr& input_media_type, | 248 const MediaTypePtr& input_media_type, |
| 241 const String& url, | |
| 242 const std::function<void()>& callback) { | 249 const std::function<void()>& callback) { |
| 243 DCHECK(input_media_type); | 250 DCHECK(input_media_type); |
| 244 DCHECK(stream->decoded_producer_); | 251 DCHECK(stream->decoded_producer_); |
| 245 DCHECK(factory_); | 252 DCHECK(factory_); |
| 246 | 253 |
| 247 factory_->CreateSink(url, input_media_type.Clone(), GetProxy(&stream->sink_)); | 254 factory_->CreateSink(stream->renderer_.Pass(), input_media_type.Clone(), |
| 255 GetProxy(&stream->sink_)); |
| 248 | 256 |
| 249 MediaTimelineControlSitePtr timeline_control_site; | 257 MediaTimelineControlSitePtr timeline_control_site; |
| 250 stream->sink_->GetTimelineControlSite(GetProxy(&timeline_control_site)); | 258 stream->sink_->GetTimelineControlSite(GetProxy(&timeline_control_site)); |
| 251 | 259 |
| 252 timeline_controller_->AddControlSite(timeline_control_site.Pass()); | 260 timeline_controller_->AddControlSite(timeline_control_site.Pass()); |
| 253 | 261 |
| 254 MediaConsumerPtr consumer; | 262 MediaConsumerPtr consumer; |
| 255 stream->sink_->GetConsumer(GetProxy(&consumer)); | 263 stream->sink_->GetConsumer(GetProxy(&consumer)); |
| 256 | 264 |
| 257 stream->decoded_producer_->Connect(consumer.Pass(), | 265 stream->decoded_producer_->Connect(consumer.Pass(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 HandleTimelineControlSiteStatusUpdates(version, status.Pass()); | 298 HandleTimelineControlSiteStatusUpdates(version, status.Pass()); |
| 291 }); | 299 }); |
| 292 } | 300 } |
| 293 | 301 |
| 294 MediaPlayerImpl::Stream::Stream() {} | 302 MediaPlayerImpl::Stream::Stream() {} |
| 295 | 303 |
| 296 MediaPlayerImpl::Stream::~Stream() {} | 304 MediaPlayerImpl::Stream::~Stream() {} |
| 297 | 305 |
| 298 } // namespace media | 306 } // namespace media |
| 299 } // namespace mojo | 307 } // namespace mojo |
| OLD | NEW |