OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MOJO_SERVICES_MEDIA_FACTORY_TIMELINE_CONTROLLER_IMPL_H_ |
| 6 #define MOJO_SERVICES_MEDIA_FACTORY_TIMELINE_CONTROLLER_IMPL_H_ |
| 7 |
| 8 #include <memory> |
| 9 #include <vector> |
| 10 |
| 11 #include "mojo/public/cpp/bindings/binding.h" |
| 12 #include "mojo/services/media/common/cpp/local_time.h" |
| 13 #include "mojo/services/media/common/cpp/timeline.h" |
| 14 #include "mojo/services/media/common/cpp/timeline_function.h" |
| 15 #include "mojo/services/media/core/interfaces/timeline_controller.mojom.h" |
| 16 #include "services/media/common/mojo_publisher.h" |
| 17 #include "services/media/factory_service/factory_service.h" |
| 18 #include "services/media/framework/util/callback_joiner.h" |
| 19 |
| 20 namespace mojo { |
| 21 namespace media { |
| 22 |
| 23 // Mojo agent that controls timing in a graph. |
| 24 class MediaTimelineControllerImpl |
| 25 : public MediaFactoryService::Product<MediaTimelineController>, |
| 26 public MediaTimelineController, |
| 27 public MediaTimelineControlSite, |
| 28 public TimelineConsumer { |
| 29 public: |
| 30 static std::shared_ptr<MediaTimelineControllerImpl> Create( |
| 31 InterfaceRequest<MediaTimelineController> request, |
| 32 MediaFactoryService* owner); |
| 33 |
| 34 ~MediaTimelineControllerImpl() override; |
| 35 |
| 36 // MediaTimelineController implementation. |
| 37 void AddControlSite( |
| 38 InterfaceHandle<MediaTimelineControlSite> control_site) override; |
| 39 |
| 40 void GetControlSite( |
| 41 InterfaceRequest<MediaTimelineControlSite> control_site) override; |
| 42 |
| 43 // MediaTimelineControlSite implementation. |
| 44 void GetStatus(uint64_t version_last_seen, |
| 45 const GetStatusCallback& callback) override; |
| 46 |
| 47 void GetTimelineConsumer( |
| 48 InterfaceRequest<TimelineConsumer> timeline_consumer) override; |
| 49 |
| 50 // TimelineConsumer implementation. |
| 51 void SetTimelineTransform( |
| 52 int64_t subject_time, |
| 53 uint32_t reference_delta, |
| 54 uint32_t subject_delta, |
| 55 int64_t effective_reference_time, |
| 56 int64_t effective_subject_time, |
| 57 const SetTimelineTransformCallback& callback) override; |
| 58 |
| 59 private: |
| 60 static constexpr int64_t kDefaultLeadTime = Timeline::ns_from_ms(30); |
| 61 |
| 62 // Relationship to subordinate control site. |
| 63 struct SiteState { |
| 64 SiteState(MediaTimelineControllerImpl* parent, |
| 65 MediaTimelineControlSitePtr site); |
| 66 |
| 67 SiteState(SiteState&& other); |
| 68 |
| 69 ~SiteState(); |
| 70 |
| 71 void HandleStatusUpdates( |
| 72 uint64_t version = MediaTimelineControlSite::kInitialStatus, |
| 73 MediaTimelineControlSiteStatusPtr status = nullptr); |
| 74 |
| 75 MediaTimelineControllerImpl* parent_; |
| 76 MediaTimelineControlSitePtr site_; |
| 77 TimelineConsumerPtr consumer_; |
| 78 bool end_of_stream_ = false; |
| 79 }; |
| 80 |
| 81 class TimelineTransition |
| 82 : public std::enable_shared_from_this<TimelineTransition> { |
| 83 public: |
| 84 TimelineTransition(int64_t reference_time, |
| 85 int64_t subject_time, |
| 86 uint32_t reference_delta, |
| 87 uint32_t subject_delta, |
| 88 const SetTimelineTransformCallback& callback); |
| 89 |
| 90 ~TimelineTransition(); |
| 91 |
| 92 // Calls returns a new callback for a child (site) transition. THIS METHOD |
| 93 // WILL ONLY WORK IF THERE IS ALREADY A SHARED POINTER TO THIS OBJECT. |
| 94 std::function<void(bool)> NewCallback() { |
| 95 callback_joiner_.Spawn(); |
| 96 |
| 97 std::shared_ptr<TimelineTransition> this_ptr = shared_from_this(); |
| 98 DCHECK(!this_ptr.unique()); |
| 99 |
| 100 return [this_ptr](bool completed) { |
| 101 DCHECK(this_ptr); |
| 102 if (!completed && !this_ptr->cancelled_) { |
| 103 LOG(WARNING) << "A site transition was cancelled unexpectedly."; |
| 104 } |
| 105 this_ptr->callback_joiner_.Complete(); |
| 106 }; |
| 107 } |
| 108 |
| 109 // Cancels this transition. |
| 110 void Cancel() { |
| 111 DCHECK(!cancelled_); |
| 112 cancelled_ = true; |
| 113 DCHECK(callback_.is_null()); |
| 114 callback_.Run(false); |
| 115 callback_.reset(); |
| 116 completed_callback_.reset(); |
| 117 } |
| 118 |
| 119 // Specifies a callback to be called if and when the transition is complete. |
| 120 // The callback will never be called if the transition is cancelled. |
| 121 void WhenCompleted(const mojo::Callback<void()>& completed_callback) { |
| 122 DCHECK(completed_callback_.is_null()); |
| 123 if (callback_.is_null() && !cancelled_) { |
| 124 completed_callback.Run(); |
| 125 } else { |
| 126 completed_callback_ = completed_callback; |
| 127 } |
| 128 } |
| 129 |
| 130 // Returns the TimelineFunction that will result from this transition. |
| 131 const TimelineFunction& new_timeline_function() const { |
| 132 return new_timeline_function_; |
| 133 } |
| 134 |
| 135 private: |
| 136 TimelineFunction new_timeline_function_; |
| 137 SetTimelineTransformCallback callback_; |
| 138 CallbackJoiner callback_joiner_; |
| 139 bool cancelled_ = false; |
| 140 Callback<void()> completed_callback_; |
| 141 }; |
| 142 |
| 143 MediaTimelineControllerImpl(InterfaceRequest<MediaTimelineController> request, |
| 144 MediaFactoryService* owner); |
| 145 |
| 146 // Takes action when a site changes its end-of-stream value. |
| 147 void HandleSiteEndOfStreamChange(); |
| 148 |
| 149 Binding<MediaTimelineControlSite> control_site_binding_; |
| 150 Binding<TimelineConsumer> consumer_binding_; |
| 151 MojoPublisher<GetStatusCallback> status_publisher_; |
| 152 std::vector<SiteState> site_states_; |
| 153 TimelineFunction current_timeline_function_; |
| 154 bool end_of_stream_; |
| 155 std::weak_ptr<TimelineTransition> pending_transition_; |
| 156 }; |
| 157 |
| 158 } // namespace media |
| 159 } // namespace mojo |
| 160 |
| 161 #endif // MOJO_SERVICES_MEDIA_FACTORY_TIMELINE_CONTROLLER_IMPL_H_ |
OLD | NEW |