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

Unified Diff: components/copresence/handlers/audio/audio_directive_list.cc

Issue 419073002: Add the copresence DirectiveHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review comments Created 6 years, 5 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
Index: components/copresence/handlers/audio/audio_directive_list.cc
diff --git a/components/copresence/handlers/audio/audio_directive_list.cc b/components/copresence/handlers/audio/audio_directive_list.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f590c392fbaf69a1a3e367705665745d75ba6c7e
--- /dev/null
+++ b/components/copresence/handlers/audio/audio_directive_list.cc
@@ -0,0 +1,146 @@
+// Copyright 2014 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 "components/copresence/handlers/audio/audio_directive_list.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "media/base/audio_bus.h"
+
+namespace {
+
+// UrlSafe is defined as:
+// '/' represented by a '_' and '+' represented by a '-'
+// TODO(rkc): Move this processing to the whispernet wrapper.
+std::string FromUrlSafe(std::string token) {
+ base::ReplaceChars(token, "-", "+", &token);
+ base::ReplaceChars(token, "_", "/", &token);
+ return token;
+}
+
+const int kSampleExpiryTimeMs = 60 * 60 * 1000; // 60 minutes.
+const int kMaxSamples = 10000;
+
+} // namespace
+
+namespace copresence {
+
+// Public methods.
+
+AudioDirective::AudioDirective() {
+}
+
+AudioDirective::AudioDirective(const std::string& op_id, base::Time end_time)
+ : op_id(op_id), end_time(end_time) {
+}
+
+AudioDirective::AudioDirective(const std::string& token,
+ const std::string& op_id,
+ base::Time end_time)
+ : token(token), op_id(op_id), end_time(end_time) {
+}
+
+AudioDirective::AudioDirective(
+ const std::string& token,
+ const std::string& op_id,
+ base::Time end_time,
+ const scoped_refptr<media::AudioBusRefCounted>& samples)
+ : token(token), op_id(op_id), end_time(end_time), samples(samples) {
+}
+
+AudioDirective::~AudioDirective() {
+}
+
+AudioDirectiveList::AudioDirectiveList(
+ const EncodeTokenCallback& encode_token_callback,
+ const base::Closure& token_added_callback)
+ : encode_token_callback_(encode_token_callback),
+ token_added_callback_(token_added_callback),
+ samples_cache_(base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
+ kMaxSamples) {
+}
+
+AudioDirectiveList::~AudioDirectiveList() {
+}
+
+void AudioDirectiveList::AddTransmitDirective(const std::string& token,
+ const std::string& op_id,
+ base::TimeDelta ttl) {
+ std::string valid_token = FromUrlSafe(token);
+ base::Time end_time = base::Time::Now() + ttl;
+
+ if (samples_cache_.HasKey(valid_token)) {
+ active_transmit_tokens_.push(AudioDirective(
+ valid_token, op_id, end_time, samples_cache_.GetValue(valid_token)));
+ return;
+ }
+
+ // If an encode request for this token has been sent, don't send it again.
+ if (pending_transmit_tokens_.find(valid_token) !=
+ pending_transmit_tokens_.end()) {
+ return;
+ }
+
+ pending_transmit_tokens_[valid_token] =
+ AudioDirective(valid_token, op_id, end_time);
+ // All whispernet callbacks will be cleared before we are destructed, so
+ // unretained is safe to use here.
+ encode_token_callback_.Run(
+ valid_token,
+ base::Bind(&AudioDirectiveList::OnTokenEncoded, base::Unretained(this)));
+}
+
+void AudioDirectiveList::AddReceiveDirective(const std::string& op_id,
+ base::TimeDelta ttl) {
+ active_receive_tokens_.push(AudioDirective(op_id, base::Time::Now() + ttl));
+}
+
+scoped_ptr<AudioDirective> AudioDirectiveList::GetNextTransmit() {
+ return GetNextFromList(&active_transmit_tokens_);
+}
+
+scoped_ptr<AudioDirective> AudioDirectiveList::GetNextReceive() {
+ return GetNextFromList(&active_receive_tokens_);
+}
+
+scoped_ptr<AudioDirective> AudioDirectiveList::GetNextFromList(
+ AudioDirectiveQueue* list) {
+ CHECK(list);
+
+ // Checks if we have any valid tokens at all (since the top of the list is
+ // always pointing to the token with the latest expiry time). If we don't
+ // have any valid tokens left, clear the list.
+ while (!list->empty() && list->top().end_time < base::Time::Now()) {
xiyuan 2014/07/29 00:22:26 Can we do: if (!list->empty() && list->top().end_
rkc 2014/07/29 00:33:36 Done.
+ while (!list->empty())
+ list->pop();
+ }
+
+ if (list->empty())
+ return make_scoped_ptr<AudioDirective>(NULL);
+
+ return make_scoped_ptr(new AudioDirective(list->top()));
+}
+
+void AudioDirectiveList::OnTokenEncoded(
+ const std::string& token,
+ const scoped_refptr<media::AudioBusRefCounted>& samples) {
+ // We shouldn't re-encode a token if it's already in the cache.
+ DCHECK(!samples_cache_.HasKey(token));
+ DVLOG(3) << "Token: " << token << " encoded.";
+ samples_cache_.Add(token, samples);
+
+ // Copy the samples into its corresponding directive object and move
+ // that object into the active queue. TODO(rkc): The actual directive without
+ // the samples is small, but we should find a better way to move around
+ // the samples vector.
+ pending_transmit_tokens_[token].samples = samples;
+ active_transmit_tokens_.push(pending_transmit_tokens_[token]);
+ pending_transmit_tokens_.erase(token);
+
+ if (!token_added_callback_.is_null())
+ token_added_callback_.Run();
+}
+
+} // namespace copresence

Powered by Google App Engine
This is Rietveld 408576698