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

Side by Side Diff: content/browser/media/capture/audio_mirroring_manager.cc

Issue 1897953003: Unmute Tab Audio For Desktop Share (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit Created 4 years, 6 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/browser/media/capture/audio_mirroring_manager.h" 5 #include "content/browser/media/capture/audio_mirroring_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 InitiateQueriesToFindNewDestination(NULL, candidates); 55 InitiateQueriesToFindNewDestination(NULL, candidates);
56 } 56 }
57 57
58 void AudioMirroringManager::RemoveDiverter(Diverter* diverter) { 58 void AudioMirroringManager::RemoveDiverter(Diverter* diverter) {
59 DCHECK(thread_checker_.CalledOnValidThread()); 59 DCHECK(thread_checker_.CalledOnValidThread());
60 60
61 // Find and remove the entry from the routing table. If the stream is being 61 // Find and remove the entry from the routing table. If the stream is being
62 // diverted, it is stopped. 62 // diverted, it is stopped.
63 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) { 63 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
64 if (it->diverter == diverter) { 64 if (it->diverter == diverter) {
65 ChangeRoute(&(*it), NULL); 65 // Stop the diverted flow.
66 RouteDivertedFlow(&(*it), NULL);
67
68 // Stop duplication flows.
69 for (auto& dup : it->duplications) {
70 diverter->StopDuplicating(dup.second);
71 }
66 routes_.erase(it); 72 routes_.erase(it);
67 return; 73 return;
68 } 74 }
69 } 75 }
70 NOTREACHED(); 76 NOTREACHED();
71 } 77 }
72 78
73 void AudioMirroringManager::StartMirroring(MirroringDestination* destination) { 79 void AudioMirroringManager::StartMirroring(MirroringDestination* destination) {
74 DCHECK(thread_checker_.CalledOnValidThread()); 80 DCHECK(thread_checker_.CalledOnValidThread());
75 DCHECK(destination); 81 DCHECK(destination);
76 82
77 // Insert an entry into the set of active mirroring sessions, if this is a 83 // Insert an entry into the set of active mirroring sessions, if this is a
78 // previously-unknown destination. 84 // previously-unknown destination.
79 if (std::find(sessions_.begin(), sessions_.end(), destination) == 85 if (std::find(sessions_.begin(), sessions_.end(), destination) ==
80 sessions_.end()) { 86 sessions_.end()) {
81 sessions_.push_back(destination); 87 sessions_.push_back(destination);
82 } 88 }
83 89
90 std::set<SourceFrameRef> candidates;
91
84 // Query the MirroringDestination to see which of the audio streams should be 92 // Query the MirroringDestination to see which of the audio streams should be
85 // diverted. 93 // diverted.
86 std::set<SourceFrameRef> candidates;
87 for (StreamRoutes::const_iterator it = routes_.begin(); it != routes_.end(); 94 for (StreamRoutes::const_iterator it = routes_.begin(); it != routes_.end();
88 ++it) { 95 ++it) {
89 if (!it->destination || it->destination == destination)
90 candidates.insert(it->source_render_frame); 96 candidates.insert(it->source_render_frame);
91 } 97 }
92 if (!candidates.empty()) { 98 if (!candidates.empty()) {
93 destination->QueryForMatches( 99 destination->QueryForMatches(
94 candidates, 100 candidates,
95 base::Bind(&AudioMirroringManager::UpdateRoutesToDestination, 101 base::Bind(&AudioMirroringManager::UpdateRoutesToDestination,
96 base::Unretained(this), 102 base::Unretained(this),
97 destination, 103 destination,
98 false)); 104 false));
99 } 105 }
100 } 106 }
101 107
102 void AudioMirroringManager::StopMirroring(MirroringDestination* destination) { 108 void AudioMirroringManager::StopMirroring(MirroringDestination* destination) {
103 DCHECK(thread_checker_.CalledOnValidThread()); 109 DCHECK(thread_checker_.CalledOnValidThread());
104 110
105 // Stop diverting each audio stream in the mirroring session being stopped. 111 // Stop diverting each audio stream in the mirroring session being stopped.
106 // Each stopped stream becomes a candidate to be diverted to another 112 // Each stopped stream becomes a candidate to be diverted to another
107 // destination. 113 // destination.
108 std::set<SourceFrameRef> redivert_candidates; 114 std::set<SourceFrameRef> redivert_candidates;
109 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) { 115 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
110 if (it->destination == destination) { 116 if (it->destination == destination) {
111 ChangeRoute(&(*it), NULL); 117 RouteDivertedFlow(&(*it), NULL);
112 redivert_candidates.insert(it->source_render_frame); 118 redivert_candidates.insert(it->source_render_frame);
113 } 119 }
120 auto dup_it = it->duplications.find(destination);
121 if (dup_it != it->duplications.end()) {
122 it->diverter->StopDuplicating(dup_it->second);
123 it->duplications.erase(dup_it);
124 }
114 } 125 }
115 if (!redivert_candidates.empty()) 126 if (!redivert_candidates.empty())
116 InitiateQueriesToFindNewDestination(destination, redivert_candidates); 127 InitiateQueriesToFindNewDestination(destination, redivert_candidates);
117 128
118 // Remove the entry from the set of active mirroring sessions. 129 // Remove the entry from the set of active mirroring sessions.
119 const Destinations::iterator dest_it = 130 const Destinations::iterator dest_it =
120 std::find(sessions_.begin(), sessions_.end(), destination); 131 std::find(sessions_.begin(), sessions_.end(), destination);
121 if (dest_it == sessions_.end()) { 132 if (dest_it == sessions_.end()) {
122 NOTREACHED(); 133 NOTREACHED();
123 return; 134 return;
124 } 135 }
125 sessions_.erase(dest_it); 136 sessions_.erase(dest_it);
126 } 137 }
127 138
128 void AudioMirroringManager::InitiateQueriesToFindNewDestination( 139 void AudioMirroringManager::InitiateQueriesToFindNewDestination(
129 MirroringDestination* old_destination, 140 MirroringDestination* old_destination,
130 const std::set<SourceFrameRef>& candidates) { 141 const std::set<SourceFrameRef>& candidates) {
131 DCHECK(thread_checker_.CalledOnValidThread()); 142 DCHECK(thread_checker_.CalledOnValidThread());
132 143
133 for (Destinations::const_iterator it = sessions_.begin(); 144 for (Destinations::const_iterator it = sessions_.begin();
134 it != sessions_.end(); ++it) { 145 it != sessions_.end(); ++it) {
135 if (*it != old_destination) { 146 if (*it == old_destination)
136 (*it)->QueryForMatches( 147 continue;
137 candidates, 148
138 base::Bind(&AudioMirroringManager::UpdateRoutesToDestination, 149 (*it)->QueryForMatches(
139 base::Unretained(this), 150 candidates,
140 *it, 151 base::Bind(&AudioMirroringManager::UpdateRoutesToDestination,
141 true)); 152 base::Unretained(this), *it, true));
142 }
143 } 153 }
144 } 154 }
145 155
146 void AudioMirroringManager::UpdateRoutesToDestination( 156 void AudioMirroringManager::UpdateRoutesToDestination(
147 MirroringDestination* destination, 157 MirroringDestination* destination,
148 bool add_only, 158 bool add_only,
159 const std::set<SourceFrameRef>& matches,
160 bool is_duplicate) {
161 if (is_duplicate)
162 UpdateRoutesToDuplicateDestination(destination, add_only, matches);
163 else
164 UpdateRoutesToDivertDestination(destination, add_only, matches);
165 }
166
167 void AudioMirroringManager::UpdateRoutesToDivertDestination(
168 MirroringDestination* destination,
169 bool add_only,
149 const std::set<SourceFrameRef>& matches) { 170 const std::set<SourceFrameRef>& matches) {
150 DCHECK(thread_checker_.CalledOnValidThread()); 171 DCHECK(thread_checker_.CalledOnValidThread());
151 172
152 if (std::find(sessions_.begin(), sessions_.end(), destination) == 173 if (std::find(sessions_.begin(), sessions_.end(), destination) ==
153 sessions_.end()) { 174 sessions_.end()) {
154 return; // Query result callback invoked after StopMirroring(). 175 return; // Query result callback invoked after StopMirroring().
155 } 176 }
156 177
157 DVLOG(1) << (add_only ? "Add " : "Replace with ") << matches.size() 178 DVLOG(1) << (add_only ? "Add " : "Replace with ") << matches.size()
158 << " routes to MirroringDestination@" << destination; 179 << " routes to MirroringDestination@" << destination;
159 180
160 // Start/stop diverting based on |matches|. Any stopped stream becomes a 181 // Start/stop diverting based on |matches|. Any stopped stream becomes a
161 // candidate to be diverted to another destination. 182 // candidate to be diverted to another destination.
162 std::set<SourceFrameRef> redivert_candidates; 183 std::set<SourceFrameRef> redivert_candidates;
163 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) { 184 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
164 if (matches.find(it->source_render_frame) != matches.end()) { 185 if (matches.find(it->source_render_frame) != matches.end()) {
165 // Only change the route if the stream is not already being diverted. 186 // Only change the route if the stream is not already being diverted.
166 if (!it->destination) 187 if (!it->destination)
167 ChangeRoute(&(*it), destination); 188 RouteDivertedFlow(&(*it), destination);
168 } else if (!add_only) { 189 } else if (!add_only) {
169 // Only stop diverting if the stream is currently routed to |destination|. 190 // Only stop diverting if the stream is currently routed to |destination|.
170 if (it->destination == destination) { 191 if (it->destination == destination) {
171 ChangeRoute(&(*it), NULL); 192 RouteDivertedFlow(&(*it), NULL);
172 redivert_candidates.insert(it->source_render_frame); 193 redivert_candidates.insert(it->source_render_frame);
173 } 194 }
174 } 195 }
175 } 196 }
176 if (!redivert_candidates.empty()) 197 if (!redivert_candidates.empty())
177 InitiateQueriesToFindNewDestination(destination, redivert_candidates); 198 InitiateQueriesToFindNewDestination(destination, redivert_candidates);
178 } 199 }
179 200
201 void AudioMirroringManager::UpdateRoutesToDuplicateDestination(
202 MirroringDestination* destination,
203 bool add_only,
204 const std::set<SourceFrameRef>& matches) {
205 DCHECK(thread_checker_.CalledOnValidThread());
206 if (std::find(sessions_.begin(), sessions_.end(), destination) ==
207 sessions_.end()) {
208 return; // Query result callback invoked after StopMirroring().
209 }
210
211 for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
212 if (matches.find(it->source_render_frame) != matches.end()) {
213 // The same destination cannot have both a diverted audio flow and a
214 // duplicated flow from the same source.
215 DCHECK_NE(it->destination, destination);
216
217 media::AudioPushSink*& pusher = it->duplications[destination];
218 if (!pusher) {
219 pusher = destination->AddPushInput(it->diverter->GetAudioParameters());
220 DCHECK(pusher);
221 it->diverter->StartDuplicating(pusher);
222 }
223 } else if (!add_only) {
224 auto dup_it = it->duplications.find(destination);
225 if (dup_it != it->duplications.end()) {
226 it->diverter->StopDuplicating(dup_it->second);
227 it->duplications.erase(dup_it);
228 }
229 }
230 }
231 }
232
180 // static 233 // static
181 void AudioMirroringManager::ChangeRoute( 234 void AudioMirroringManager::RouteDivertedFlow(
182 StreamRoutingState* route, MirroringDestination* new_destination) { 235 StreamRoutingState* route,
236 MirroringDestination* new_destination) {
237 // The same destination cannot have both a diverted audio flow and a
238 // duplicated flow from the same source.
239 DCHECK(route->duplications.find(new_destination) ==
240 route->duplications.end());
241
183 if (route->destination == new_destination) 242 if (route->destination == new_destination)
184 return; // No change. 243 return; // No change.
185 244
186 if (route->destination) { 245 if (route->destination) {
187 DVLOG(1) << "Stop diverting render_process_id:render_frame_id=" 246 DVLOG(1) << "Stop diverting render_process_id:render_frame_id="
188 << route->source_render_frame.first << ':' 247 << route->source_render_frame.first << ':'
189 << route->source_render_frame.second 248 << route->source_render_frame.second
190 << " --> MirroringDestination@" << route->destination; 249 << " --> MirroringDestination@" << route->destination;
191 route->diverter->StopDiverting(); 250 route->diverter->StopDiverting();
192 route->destination = NULL; 251 route->destination = NULL;
(...skipping 15 matching lines...) Expand all
208 : source_render_frame(source_frame), 267 : source_render_frame(source_frame),
209 diverter(stream_diverter), 268 diverter(stream_diverter),
210 destination(NULL) {} 269 destination(NULL) {}
211 270
212 AudioMirroringManager::StreamRoutingState::StreamRoutingState( 271 AudioMirroringManager::StreamRoutingState::StreamRoutingState(
213 const StreamRoutingState& other) = default; 272 const StreamRoutingState& other) = default;
214 273
215 AudioMirroringManager::StreamRoutingState::~StreamRoutingState() {} 274 AudioMirroringManager::StreamRoutingState::~StreamRoutingState() {}
216 275
217 } // namespace content 276 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698