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

Side by Side Diff: components/copresence/handlers/audio/audio_directive_list.cc

Issue 461803003: Stop playing/recording when not needed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/copresence/handlers/audio/audio_directive_list.h" 5 #include "components/copresence/handlers/audio/audio_directive_list.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/string_util.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "media/base/audio_bus.h" 10 #include "base/time/time.h"
11
12 namespace {
13
14 // UrlSafe is defined as:
15 // '/' represented by a '_' and '+' represented by a '-'
16 // TODO(rkc): Move this processing to the whispernet wrapper.
17 std::string FromUrlSafe(std::string token) {
18 base::ReplaceChars(token, "-", "+", &token);
19 base::ReplaceChars(token, "_", "/", &token);
20 return token;
21 }
22
23 const int kSampleExpiryTimeMs = 60 * 60 * 1000; // 60 minutes.
24 const int kMaxSamples = 10000;
25
26 } // namespace
27 11
28 namespace copresence { 12 namespace copresence {
29 13
30 // Public methods. 14 // Public methods.
31 15
32 AudioDirective::AudioDirective() { 16 AudioDirective::AudioDirective() {
33 } 17 }
34 18
35 AudioDirective::AudioDirective(const std::string& token, 19 AudioDirective::AudioDirective(const std::string& op_id, base::Time end_time)
36 const std::string& op_id, 20 : op_id(op_id), end_time(end_time) {
37 base::Time end_time)
38 : token(token), op_id(op_id), end_time(end_time) {
39 } 21 }
40 22
41 AudioDirective::AudioDirective( 23 AudioDirectiveList::AudioDirectiveList() {
42 const std::string& token,
43 const std::string& op_id,
44 base::Time end_time,
45 const scoped_refptr<media::AudioBusRefCounted>& samples)
46 : token(token), op_id(op_id), end_time(end_time), samples(samples) {
47 }
48
49 AudioDirective::~AudioDirective() {
50 }
51
52 AudioDirectiveList::AudioDirectiveList(
53 const EncodeTokenCallback& encode_token_callback,
54 const base::Closure& token_added_callback,
55 bool use_audible_encoding)
56 : encode_token_callback_(encode_token_callback),
57 token_added_callback_(token_added_callback),
58 use_audible_encoding_(use_audible_encoding),
59 samples_cache_(base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
60 kMaxSamples) {
61 } 24 }
62 25
63 AudioDirectiveList::~AudioDirectiveList() { 26 AudioDirectiveList::~AudioDirectiveList() {
64 } 27 }
65 28
66 void AudioDirectiveList::AddTransmitDirective(const std::string& token, 29 void AudioDirectiveList::AddDirective(const std::string& op_id,
67 const std::string& op_id, 30 base::TimeDelta ttl) {
68 base::TimeDelta ttl) {
69 std::string valid_token = FromUrlSafe(token);
70 base::Time end_time = base::Time::Now() + ttl; 31 base::Time end_time = base::Time::Now() + ttl;
71 32
72 if (samples_cache_.HasKey(valid_token)) { 33 // In case this op is already in the list, update it instead of adding
73 active_transmit_tokens_.push(AudioDirective( 34 // it again.
74 valid_token, op_id, end_time, samples_cache_.GetValue(valid_token))); 35 std::vector<AudioDirective>::iterator it = FindDirectiveByOpId(op_id);
36 if (it != active_directives_.end()) {
37 it->end_time = end_time;
38 std::make_heap(active_directives_.begin(),
39 active_directives_.end(),
40 LatestFirstComparator());
75 return; 41 return;
76 } 42 }
77 43
78 // If an encode request for this token has been sent, don't send it again. 44 active_directives_.push_back(AudioDirective(op_id, end_time));
79 if (pending_transmit_tokens_.find(valid_token) != 45 std::push_heap(active_directives_.begin(),
80 pending_transmit_tokens_.end()) { 46 active_directives_.end(),
81 return; 47 LatestFirstComparator());
48 }
49
50 void AudioDirectiveList::RemoveDirective(const std::string& op_id) {
51 std::vector<AudioDirective>::iterator it = FindDirectiveByOpId(op_id);
52 if (it != active_directives_.end())
53 active_directives_.erase(it);
54
55 std::make_heap(active_directives_.begin(),
56 active_directives_.end(),
57 LatestFirstComparator());
58 }
59
60 scoped_ptr<AudioDirective> AudioDirectiveList::GetActiveDirective() {
61 // The top is always the instruction that is ending the latest. If that time
62 // has passed, means all our previous instructions have expired too, hence
63 // clear the list.
64 if (!active_directives_.empty() &&
65 active_directives_.front().end_time < base::Time::Now()) {
66 active_directives_.clear();
82 } 67 }
83 68
84 pending_transmit_tokens_[valid_token] = 69 if (active_directives_.empty())
85 AudioDirective(valid_token, op_id, end_time); 70 return make_scoped_ptr<AudioDirective>(NULL);
86 // All whispernet callbacks will be cleared before we are destructed, so 71
87 // unretained is safe to use here. 72 return make_scoped_ptr(new AudioDirective(active_directives_.front()));
88 encode_token_callback_.Run(
89 valid_token,
90 use_audible_encoding_,
91 base::Bind(&AudioDirectiveList::OnTokenEncoded, base::Unretained(this)));
92 } 73 }
93 74
94 void AudioDirectiveList::AddReceiveDirective(const std::string& op_id, 75 std::vector<AudioDirective>::iterator AudioDirectiveList::FindDirectiveByOpId(
95 base::TimeDelta ttl) { 76 const std::string& op_id) {
96 active_receive_tokens_.push( 77 for (std::vector<AudioDirective>::iterator it = active_directives_.begin();
97 AudioDirective(std::string(), op_id, base::Time::Now() + ttl)); 78 it != active_directives_.end();
98 } 79 ++it) {
99 80 if (it->op_id == op_id)
100 scoped_ptr<AudioDirective> AudioDirectiveList::GetNextTransmit() { 81 return it;
101 return GetNextFromList(&active_transmit_tokens_);
102 }
103
104 scoped_ptr<AudioDirective> AudioDirectiveList::GetNextReceive() {
105 return GetNextFromList(&active_receive_tokens_);
106 }
107
108 scoped_ptr<AudioDirective> AudioDirectiveList::GetNextFromList(
109 AudioDirectiveQueue* list) {
110 CHECK(list);
111
112 // Checks if we have any valid tokens at all (since the top of the list is
113 // always pointing to the token with the latest expiry time). If we don't
114 // have any valid tokens left, clear the list.
115 if (!list->empty() && list->top().end_time < base::Time::Now()) {
116 while (!list->empty())
117 list->pop();
118 } 82 }
119 83 return active_directives_.end();
120 if (list->empty())
121 return make_scoped_ptr<AudioDirective>(NULL);
122
123 return make_scoped_ptr(new AudioDirective(list->top()));
124 }
125
126 void AudioDirectiveList::OnTokenEncoded(
127 const std::string& token,
128 bool /* audible */,
129 const scoped_refptr<media::AudioBusRefCounted>& samples) {
130 // We shouldn't re-encode a token if it's already in the cache.
131 DCHECK(!samples_cache_.HasKey(token));
132 DVLOG(3) << "Token: " << token << " encoded.";
133 samples_cache_.Add(token, samples);
134
135 // Copy the samples into their corresponding directive object and move
136 // that object into the active queue.
137 std::map<std::string, AudioDirective>::iterator it =
138 pending_transmit_tokens_.find(token);
139
140 it->second.samples = samples;
141 active_transmit_tokens_.push(it->second);
142 pending_transmit_tokens_.erase(it);
143
144 if (!token_added_callback_.is_null())
145 token_added_callback_.Run();
146 } 84 }
147 85
148 } // namespace copresence 86 } // namespace copresence
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698