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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/media/common/timeline_control_site.cc
diff --git a/services/media/common/timeline_control_site.cc b/services/media/common/timeline_control_site.cc
new file mode 100644
index 0000000000000000000000000000000000000000..26dc07f214a603745aca3408e5bdd86c77683d93
--- /dev/null
+++ b/services/media/common/timeline_control_site.cc
@@ -0,0 +1,193 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/services/media/common/cpp/timeline.h"
+#include "services/media/common/timeline_control_site.h"
+
+namespace mojo {
+namespace media {
+
+// For checking preconditions when handling mojo requests.
+// Checks the condition, and, if it's false, resets and calls return.
+#define RCHECK(condition) \
+ if (!(condition)) { \
+ LOG(ERROR) << "request precondition failed: " #condition "."; \
+ ResetUnsafe(); \
+ return; \
+ }
+
+TimelineControlSite::TimelineControlSite()
+ : control_site_binding_(this), consumer_binding_(this) {
+ task_runner_ = base::MessageLoop::current()->task_runner();
+ DCHECK(task_runner_);
+
+ base::AutoLock lock(lock_);
+ ClearPendingTimelineFunctionUnsafe(false);
+
+ status_publisher_.SetCallbackRunner(
+ [this](const GetStatusCallback& callback, uint64_t version) {
+ MediaTimelineControlSiteStatusPtr status;
+ {
+ base::AutoLock lock(lock_);
+ status = MediaTimelineControlSiteStatus::New();
+ status->timeline_transform =
+ TimelineTransform::From(current_timeline_function_);
+ status->end_of_stream = false; // TODO(dalesat): Provide this.
+ }
+ callback.Run(version, status.Pass());
+ });
+}
+
+TimelineControlSite::~TimelineControlSite() {}
+
+void TimelineControlSite::Bind(
+ InterfaceRequest<MediaTimelineControlSite> request) {
+ if (control_site_binding_.is_bound()) {
+ control_site_binding_.Close();
+ }
+
+ control_site_binding_.Bind(request.Pass());
+}
+
+void TimelineControlSite::Reset() {
+ if (control_site_binding_.is_bound()) {
+ control_site_binding_.Close();
+ }
+
+ if (consumer_binding_.is_bound()) {
+ consumer_binding_.Close();
+ }
+
+ {
+ base::AutoLock lock(lock_);
+ current_timeline_function_ = TimelineFunction();
+ ClearPendingTimelineFunctionUnsafe(false);
+ generation_ = 1;
+ }
+
+ status_publisher_.SendUpdates();
+}
+
+void TimelineControlSite::SnapshotCurrentFunction(int64_t reference_time,
+ TimelineFunction* out,
+ uint32_t* generation) {
+ DCHECK(out);
+ base::AutoLock lock(lock_);
+ ApplyPendingChangesUnsafe(reference_time);
+ *out = current_timeline_function_;
+ if (generation) {
+ *generation = generation_;
+ }
+}
+
+void TimelineControlSite::GetStatus(uint64_t version_last_seen,
+ const GetStatusCallback& callback) {
+ status_publisher_.Get(version_last_seen, callback);
+}
+
+void TimelineControlSite::GetTimelineConsumer(
+ InterfaceRequest<TimelineConsumer> timeline_consumer) {
+ if (consumer_binding_.is_bound()) {
+ consumer_binding_.Close();
+ }
+
+ consumer_binding_.Bind(timeline_consumer.Pass());
+}
+
+void TimelineControlSite::SetTimelineTransform(
+ int64_t subject_time,
+ uint32_t reference_delta,
+ uint32_t subject_delta,
+ int64_t effective_reference_time,
+ int64_t effective_subject_time,
+ const SetTimelineTransformCallback& callback) {
+ base::AutoLock lock(lock_);
+
+ // At most one of the effective times must be specified.
+ RCHECK(effective_reference_time == kUnspecifiedTime ||
+ effective_subject_time == kUnspecifiedTime);
+ // effective_subject_time can only be used if we're progressing already.
+ RCHECK(effective_subject_time == kUnspecifiedTime ||
+ current_timeline_function_.subject_delta() != 0);
+ RCHECK(reference_delta != 0);
+
+ if (effective_subject_time != kUnspecifiedTime) {
+ // Infer effective_reference_time from effective_subject_time.
+ effective_reference_time =
+ current_timeline_function_.ApplyInverse(effective_subject_time);
+
+ if (subject_time == kUnspecifiedTime) {
+ // Infer subject_time from effective_subject_time.
+ subject_time = effective_subject_time;
+ }
+ } else {
+ if (effective_reference_time == kUnspecifiedTime) {
+ // Neither effective time was specified. Effective time is now.
+ effective_reference_time = Timeline::local_now();
+ }
+
+ if (subject_time == kUnspecifiedTime) {
+ // Infer subject_time from effective_reference_time.
+ subject_time = current_timeline_function_(effective_reference_time);
+ }
+ }
+
+ // Eject any previous pending change.
+ ClearPendingTimelineFunctionUnsafe(false);
+
+ // Queue up the new pending change.
+ pending_timeline_function_ = TimelineFunction(
+ effective_reference_time, subject_time, reference_delta, subject_delta);
+
+ set_timeline_transform_callback_ = callback;
+}
+
+void TimelineControlSite::ApplyPendingChangesUnsafe(int64_t reference_time) {
+ lock_.AssertAcquired();
+
+ if (!TimelineFunctionPendingUnsafe() ||
+ pending_timeline_function_.reference_time() > reference_time) {
+ return;
+ }
+
+ current_timeline_function_ = pending_timeline_function_;
+ ClearPendingTimelineFunctionUnsafe(true);
+
+ ++generation_;
+
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&MojoPublisher<GetStatusCallback>::SendUpdates,
+ base::Unretained(&status_publisher_)));
+}
+
+void TimelineControlSite::ClearPendingTimelineFunctionUnsafe(bool completed) {
+ lock_.AssertAcquired();
+
+ pending_timeline_function_ =
+ TimelineFunction(kUnspecifiedTime, kUnspecifiedTime, 1, 0);
+ if (!set_timeline_transform_callback_.is_null()) {
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&TimelineControlSite::RunCallback,
+ set_timeline_transform_callback_, completed));
+ set_timeline_transform_callback_.reset();
+ }
+}
+
+void TimelineControlSite::ResetUnsafe() {
+ lock_.AssertAcquired();
+ task_runner_->PostTask(FROM_HERE, base::Bind(&TimelineControlSite::Reset,
+ base::Unretained(this)));
+}
+
+// static
+void TimelineControlSite::RunCallback(SetTimelineTransformCallback callback,
+ bool completed) {
+ callback.Run(completed);
+}
+
+} // namespace media
+} // namespace mojo
« 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