Index: services/media/factory_service/media_player_impl.cc |
diff --git a/services/media/factory_service/media_player_impl.cc b/services/media/factory_service/media_player_impl.cc |
index a9632996f27bc8f6ad6860dc2fa5113bc5d5d1de..dcaa5f628b127d7b32489289bcc3455468e1e240 100644 |
--- a/services/media/factory_service/media_player_impl.cc |
+++ b/services/media/factory_service/media_player_impl.cc |
@@ -31,7 +31,7 @@ MediaPlayerImpl::MediaPlayerImpl(InterfaceHandle<SeekingReader> reader, |
uint64_t version) { |
MediaPlayerStatusPtr status = MediaPlayerStatus::New(); |
status->timeline_transform = TimelineTransform::From(timeline_function_); |
- status->end_of_stream = AllSinksAtEndOfStream(); |
+ status->end_of_stream = end_of_stream_; |
status->metadata = metadata_.Clone(); |
callback.Run(version, status.Pass()); |
}); |
@@ -41,27 +41,29 @@ MediaPlayerImpl::MediaPlayerImpl(InterfaceHandle<SeekingReader> reader, |
ConnectToService(app()->shell(), "mojo:media_factory", GetProxy(&factory_)); |
factory_->CreateDemux(reader.Pass(), GetProxy(&demux_)); |
- |
HandleDemuxMetadataUpdates(); |
+ factory_->CreateTimelineController(GetProxy(&timeline_controller_)); |
+ timeline_controller_->GetControlSite(GetProxy(&timeline_control_site_)); |
+ timeline_control_site_->GetTimelineConsumer(GetProxy(&timeline_consumer_)); |
+ HandleTimelineControlSiteStatusUpdates(); |
+ |
demux_->Describe([this](mojo::Array<MediaTypePtr> stream_types) { |
// Populate streams_ and enable the streams we want. |
std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); |
for (MediaTypePtr& stream_type : stream_types) { |
- streams_.push_back(std::unique_ptr<Stream>( |
- new Stream(streams_.size(), stream_type.Pass()))); |
+ streams_.push_back(std::unique_ptr<Stream>(new Stream())); |
Stream& stream = *streams_.back(); |
- switch (stream.media_type_->medium) { |
+ switch (stream_type->medium) { |
case MediaTypeMedium::AUDIO: |
- stream.enabled_ = true; |
- PrepareStream(&stream, "mojo:audio_server", |
- callback_joiner->NewCallback()); |
+ PrepareStream(&stream, streams_.size() - 1, stream_type, |
+ "mojo:audio_server", callback_joiner->NewCallback()); |
break; |
case MediaTypeMedium::VIDEO: |
- stream.enabled_ = true; |
// TODO(dalesat): Send video somewhere. |
- PrepareStream(&stream, "nowhere", callback_joiner->NewCallback()); |
+ PrepareStream(&stream, streams_.size() - 1, stream_type, "nowhere", |
+ callback_joiner->NewCallback()); |
break; |
// TODO(dalesat): Enable other stream types. |
default: |
@@ -91,7 +93,7 @@ void MediaPlayerImpl::Update() { |
if (target_state_ == State::kPlaying) { |
if (!flushed_) { |
- SetSinkTimelineTransforms(1, 1); |
+ SetTimelineTransform(1, 1); |
state_ = State::kWaiting; |
break; |
} |
@@ -99,7 +101,7 @@ void MediaPlayerImpl::Update() { |
flushed_ = false; |
state_ = State::kWaiting; |
demux_->Prime([this]() { |
- SetSinkTimelineTransforms(1, 1); |
+ SetTimelineTransform(1, 1); |
state_ = State::kWaiting; |
Update(); |
}); |
@@ -109,12 +111,12 @@ void MediaPlayerImpl::Update() { |
case State::kPlaying: |
if (target_position_ != kUnspecifiedTime || |
target_state_ == State::kPaused) { |
- SetSinkTimelineTransforms(1, 0); |
+ SetTimelineTransform(1, 0); |
state_ = State::kWaiting; |
break; |
} |
- if (AllSinksAtEndOfStream()) { |
+ if (end_of_stream_) { |
target_state_ = State::kPaused; |
state_ = State::kPaused; |
break; |
@@ -150,62 +152,22 @@ void MediaPlayerImpl::WhenFlushedAndSeeking() { |
}); |
} |
-void MediaPlayerImpl::SetSinkTimelineTransforms(uint32_t reference_delta, |
- uint32_t subject_delta) { |
- SetSinkTimelineTransforms( |
+void MediaPlayerImpl::SetTimelineTransform(uint32_t reference_delta, |
+ uint32_t subject_delta) { |
+ timeline_consumer_->SetTimelineTransform( |
transform_subject_time_, reference_delta, subject_delta, |
- Timeline::local_now() + kMinimumLeadTime, kUnspecifiedTime); |
-} |
+ Timeline::local_now() + kMinimumLeadTime, kUnspecifiedTime, |
+ [this, subject_delta](bool completed) { |
+ RCHECK(state_ == State::kWaiting); |
-void MediaPlayerImpl::SetSinkTimelineTransforms( |
- int64_t subject_time, |
- uint32_t reference_delta, |
- uint32_t subject_delta, |
- int64_t effective_reference_time, |
- int64_t effective_subject_time) { |
- std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); |
- |
- for (auto& stream : streams_) { |
- if (stream->enabled_) { |
- DCHECK(stream->timeline_consumer_); |
- callback_joiner->Spawn(); |
- stream->timeline_consumer_->SetTimelineTransform( |
- subject_time, reference_delta, subject_delta, |
- effective_reference_time, effective_subject_time, |
- [this, callback_joiner](bool completed) { |
- callback_joiner->Complete(); |
- }); |
- } |
- } |
- |
- transform_subject_time_ = kUnspecifiedTime; |
- |
- callback_joiner->WhenJoined([this, subject_delta]() { |
- RCHECK(state_ == State::kWaiting); |
- |
- if (subject_delta == 0) { |
- state_ = State::kPaused; |
- } else { |
- state_ = State::kPlaying; |
- } |
- |
- Update(); |
- }); |
-} |
- |
-bool MediaPlayerImpl::AllSinksAtEndOfStream() { |
- int result = false; |
- |
- for (auto& stream : streams_) { |
- if (stream->enabled_) { |
- result = stream->end_of_stream_; |
- if (!result) { |
- break; |
- } |
- } |
- } |
+ if (subject_delta == 0) { |
+ state_ = State::kPaused; |
+ } else { |
+ state_ = State::kPlaying; |
+ } |
- return result; |
+ Update(); |
+ }); |
} |
void MediaPlayerImpl::GetStatus(uint64_t version_last_seen, |
@@ -229,19 +191,21 @@ void MediaPlayerImpl::Seek(int64_t position) { |
} |
void MediaPlayerImpl::PrepareStream(Stream* stream, |
+ size_t index, |
+ const MediaTypePtr& input_media_type, |
const String& url, |
const std::function<void()>& callback) { |
DCHECK(factory_); |
- demux_->GetProducer(stream->index_, GetProxy(&stream->encoded_producer_)); |
+ demux_->GetProducer(index, GetProxy(&stream->encoded_producer_)); |
- if (stream->media_type_->encoding != MediaType::kAudioEncodingLpcm && |
- stream->media_type_->encoding != MediaType::kVideoEncodingUncompressed) { |
+ if (input_media_type->encoding != MediaType::kAudioEncodingLpcm && |
+ input_media_type->encoding != MediaType::kVideoEncodingUncompressed) { |
std::shared_ptr<CallbackJoiner> callback_joiner = CallbackJoiner::Create(); |
// Compressed media. Insert a decoder in front of the sink. The sink would |
// add its own internal decoder, but we want to test the decoder. |
- factory_->CreateDecoder(stream->media_type_.Clone(), |
+ factory_->CreateDecoder(input_media_type.Clone(), |
GetProxy(&stream->decoder_)); |
MediaConsumerPtr decoder_consumer; |
@@ -268,7 +232,7 @@ void MediaPlayerImpl::PrepareStream(Stream* stream, |
// would work for compressed media as well (the sink would decode), but we |
// want to test the decoder. |
stream->decoded_producer_ = stream->encoded_producer_.Pass(); |
- CreateSink(stream, stream->media_type_, url, callback); |
+ CreateSink(stream, input_media_type, url, callback); |
} |
} |
@@ -281,13 +245,11 @@ void MediaPlayerImpl::CreateSink(Stream* stream, |
DCHECK(factory_); |
factory_->CreateSink(url, input_media_type.Clone(), GetProxy(&stream->sink_)); |
- stream->sink_->GetTimelineControlSite( |
- GetProxy(&stream->timeline_control_site_)); |
- HandleTimelineControlSiteStatusUpdates(stream); |
+ MediaTimelineControlSitePtr timeline_control_site; |
+ stream->sink_->GetTimelineControlSite(GetProxy(&timeline_control_site)); |
- stream->timeline_control_site_->GetTimelineConsumer( |
- GetProxy(&stream->timeline_consumer_)); |
+ timeline_controller_->AddControlSite(timeline_control_site.Pass()); |
MediaConsumerPtr consumer; |
stream->sink_->GetConsumer(GetProxy(&consumer)); |
@@ -313,26 +275,23 @@ void MediaPlayerImpl::HandleDemuxMetadataUpdates(uint64_t version, |
} |
void MediaPlayerImpl::HandleTimelineControlSiteStatusUpdates( |
- Stream* stream, |
uint64_t version, |
MediaTimelineControlSiteStatusPtr status) { |
if (status) { |
- // TODO(dalesat): Why does one sink determine timeline_function_? |
timeline_function_ = status->timeline_transform.To<TimelineFunction>(); |
- stream->end_of_stream_ = status->end_of_stream; |
+ end_of_stream_ = status->end_of_stream; |
status_publisher_.SendUpdates(); |
Update(); |
} |
- stream->timeline_control_site_->GetStatus( |
- version, [this, stream](uint64_t version, |
- MediaTimelineControlSiteStatusPtr status) { |
- HandleTimelineControlSiteStatusUpdates(stream, version, status.Pass()); |
+ timeline_control_site_->GetStatus( |
+ version, |
+ [this](uint64_t version, MediaTimelineControlSiteStatusPtr status) { |
+ HandleTimelineControlSiteStatusUpdates(version, status.Pass()); |
}); |
} |
-MediaPlayerImpl::Stream::Stream(size_t index, MediaTypePtr media_type) |
- : index_(index), media_type_(media_type.Pass()) {} |
+MediaPlayerImpl::Stream::Stream() {} |
MediaPlayerImpl::Stream::~Stream() {} |