Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: services/media/common/timeline_control_site.cc

Issue 1986303002: Motown: Use new TimelineTransform and related definitions (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fixes per feedback. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/media/common/timeline_control_site.h ('k') | services/media/factory_service/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "base/bind.h"
6 #include "base/logging.h"
7 #include "base/message_loop/message_loop.h"
8 #include "mojo/services/media/common/cpp/timeline.h"
9 #include "services/media/common/timeline_control_site.h"
10
11 namespace mojo {
12 namespace media {
13
14 // For checking preconditions when handling mojo requests.
15 // Checks the condition, and, if it's false, resets and calls return.
16 #define RCHECK(condition) \
17 if (!(condition)) { \
18 LOG(ERROR) << "request precondition failed: " #condition "."; \
19 ResetUnsafe(); \
20 return; \
21 }
22
23 TimelineControlSite::TimelineControlSite()
24 : control_site_binding_(this), consumer_binding_(this) {
25 task_runner_ = base::MessageLoop::current()->task_runner();
26 DCHECK(task_runner_);
27
28 base::AutoLock lock(lock_);
29 ClearPendingTimelineFunctionUnsafe(false);
30
31 status_publisher_.SetCallbackRunner(
32 [this](const GetStatusCallback& callback, uint64_t version) {
33 MediaTimelineControlSiteStatusPtr status;
34 {
35 base::AutoLock lock(lock_);
36 status = MediaTimelineControlSiteStatus::New();
37 status->timeline_transform =
38 TimelineTransform::From(current_timeline_function_);
39 status->end_of_stream = false; // TODO(dalesat): Provide this.
40 }
41 callback.Run(version, status.Pass());
42 });
43 }
44
45 TimelineControlSite::~TimelineControlSite() {}
46
47 void TimelineControlSite::Bind(
48 InterfaceRequest<MediaTimelineControlSite> request) {
49 if (control_site_binding_.is_bound()) {
50 control_site_binding_.Close();
51 }
52
53 control_site_binding_.Bind(request.Pass());
54 }
55
56 void TimelineControlSite::Reset() {
57 if (control_site_binding_.is_bound()) {
58 control_site_binding_.Close();
59 }
60
61 if (consumer_binding_.is_bound()) {
62 consumer_binding_.Close();
63 }
64
65 {
66 base::AutoLock lock(lock_);
67 current_timeline_function_ = TimelineFunction();
68 ClearPendingTimelineFunctionUnsafe(false);
69 generation_ = 1;
70 }
71
72 status_publisher_.SendUpdates();
73 }
74
75 void TimelineControlSite::SnapshotCurrentFunction(int64_t reference_time,
76 TimelineFunction* out,
77 uint32_t* generation) {
78 DCHECK(out);
79 base::AutoLock lock(lock_);
80 ApplyPendingChangesUnsafe(reference_time);
81 *out = current_timeline_function_;
82 if (generation) {
83 *generation = generation_;
84 }
85 }
86
87 void TimelineControlSite::GetStatus(uint64_t version_last_seen,
88 const GetStatusCallback& callback) {
89 status_publisher_.Get(version_last_seen, callback);
90 }
91
92 void TimelineControlSite::GetTimelineConsumer(
93 InterfaceRequest<TimelineConsumer> timeline_consumer) {
94 if (consumer_binding_.is_bound()) {
95 consumer_binding_.Close();
96 }
97
98 consumer_binding_.Bind(timeline_consumer.Pass());
99 }
100
101 void TimelineControlSite::SetTimelineTransform(
102 int64_t subject_time,
103 uint32_t reference_delta,
104 uint32_t subject_delta,
105 int64_t effective_reference_time,
106 int64_t effective_subject_time,
107 const SetTimelineTransformCallback& callback) {
108 base::AutoLock lock(lock_);
109
110 // At most one of the effective times must be specified.
111 RCHECK(effective_reference_time == kUnspecifiedTime ||
112 effective_subject_time == kUnspecifiedTime);
113 // effective_subject_time can only be used if we're progressing already.
114 RCHECK(effective_subject_time == kUnspecifiedTime ||
115 current_timeline_function_.subject_delta() != 0);
116 RCHECK(reference_delta != 0);
117
118 if (effective_subject_time != kUnspecifiedTime) {
119 // Infer effective_reference_time from effective_subject_time.
120 effective_reference_time =
121 current_timeline_function_.ApplyInverse(effective_subject_time);
122
123 if (subject_time == kUnspecifiedTime) {
124 // Infer subject_time from effective_subject_time.
125 subject_time = effective_subject_time;
126 }
127 } else {
128 if (effective_reference_time == kUnspecifiedTime) {
129 // Neither effective time was specified. Effective time is now.
130 effective_reference_time = Timeline::local_now();
131 }
132
133 if (subject_time == kUnspecifiedTime) {
134 // Infer subject_time from effective_reference_time.
135 subject_time = current_timeline_function_(effective_reference_time);
136 }
137 }
138
139 // Eject any previous pending change.
140 ClearPendingTimelineFunctionUnsafe(false);
141
142 // Queue up the new pending change.
143 pending_timeline_function_ = TimelineFunction(
144 effective_reference_time, subject_time, reference_delta, subject_delta);
145
146 set_timeline_transform_callback_ = callback;
147 }
148
149 void TimelineControlSite::ApplyPendingChangesUnsafe(int64_t reference_time) {
150 lock_.AssertAcquired();
151
152 if (!TimelineFunctionPendingUnsafe() ||
153 pending_timeline_function_.reference_time() > reference_time) {
154 return;
155 }
156
157 current_timeline_function_ = pending_timeline_function_;
158 ClearPendingTimelineFunctionUnsafe(true);
159
160 ++generation_;
161
162 task_runner_->PostTask(
163 FROM_HERE, base::Bind(&MojoPublisher<GetStatusCallback>::SendUpdates,
164 base::Unretained(&status_publisher_)));
165 }
166
167 void TimelineControlSite::ClearPendingTimelineFunctionUnsafe(bool completed) {
168 lock_.AssertAcquired();
169
170 pending_timeline_function_ =
171 TimelineFunction(kUnspecifiedTime, kUnspecifiedTime, 1, 0);
172 if (!set_timeline_transform_callback_.is_null()) {
173 task_runner_->PostTask(
174 FROM_HERE, base::Bind(&TimelineControlSite::RunCallback,
175 set_timeline_transform_callback_, completed));
176 set_timeline_transform_callback_.reset();
177 }
178 }
179
180 void TimelineControlSite::ResetUnsafe() {
181 lock_.AssertAcquired();
182 task_runner_->PostTask(FROM_HERE, base::Bind(&TimelineControlSite::Reset,
183 base::Unretained(this)));
184 }
185
186 // static
187 void TimelineControlSite::RunCallback(SetTimelineTransformCallback callback,
188 bool completed) {
189 callback.Run(completed);
190 }
191
192 } // namespace media
193 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/common/timeline_control_site.h ('k') | services/media/factory_service/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698