| Index: content/browser/media/capture/audio_mirroring_manager.cc
|
| diff --git a/content/browser/media/capture/audio_mirroring_manager.cc b/content/browser/media/capture/audio_mirroring_manager.cc
|
| index f8b8b3a5b183e9d1b1ff07dd6728279b368d0c88..0fbd07cb4647d56c0b9982d5f6f397e72b6b7217 100644
|
| --- a/content/browser/media/capture/audio_mirroring_manager.cc
|
| +++ b/content/browser/media/capture/audio_mirroring_manager.cc
|
| @@ -81,9 +81,24 @@ void AudioMirroringManager::StartMirroring(MirroringDestination* destination) {
|
| sessions_.push_back(destination);
|
| }
|
|
|
| + std::set<SourceFrameRef> candidates;
|
| + if (destination->IsDuplication()) {
|
| + for (StreamRoutes::const_iterator it = routes_.begin(); it != routes_.end();
|
| + ++it) {
|
| + if (it->dup_destinations.count(destination) == 0)
|
| + candidates.insert(it->source_render_frame);
|
| + }
|
| + if (!candidates.empty()) {
|
| + destination->QueryForMatches(
|
| + candidates,
|
| + base::Bind(&AudioMirroringManager::UpdateRoutesToDupDestination,
|
| + base::Unretained(this), destination, false));
|
| + }
|
| + return;
|
| + }
|
| +
|
| // Query the MirroringDestination to see which of the audio streams should be
|
| // diverted.
|
| - std::set<SourceFrameRef> candidates;
|
| for (StreamRoutes::const_iterator it = routes_.begin(); it != routes_.end();
|
| ++it) {
|
| if (!it->destination || it->destination == destination)
|
| @@ -102,18 +117,24 @@ void AudioMirroringManager::StartMirroring(MirroringDestination* destination) {
|
| void AudioMirroringManager::StopMirroring(MirroringDestination* destination) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - // Stop diverting each audio stream in the mirroring session being stopped.
|
| - // Each stopped stream becomes a candidate to be diverted to another
|
| - // destination.
|
| - std::set<SourceFrameRef> redivert_candidates;
|
| - for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
|
| - if (it->destination == destination) {
|
| - ChangeRoute(&(*it), NULL);
|
| - redivert_candidates.insert(it->source_render_frame);
|
| + if (destination->IsDuplication()) {
|
| + std::set<SourceFrameRef> matches;
|
| + UpdateRoutesToDupDestination(destination, false, matches);
|
| + } else {
|
| + // Stop diverting each audio stream in the mirroring session being stopped.
|
| + // Each stopped stream becomes a candidate to be diverted to another
|
| + // destination.
|
| + std::set<SourceFrameRef> redivert_candidates;
|
| + for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end();
|
| + ++it) {
|
| + if (it->destination == destination) {
|
| + ChangeRoute(&(*it), NULL);
|
| + redivert_candidates.insert(it->source_render_frame);
|
| + }
|
| }
|
| + if (!redivert_candidates.empty())
|
| + InitiateQueriesToFindNewDestination(destination, redivert_candidates);
|
| }
|
| - if (!redivert_candidates.empty())
|
| - InitiateQueriesToFindNewDestination(destination, redivert_candidates);
|
|
|
| // Remove the entry from the set of active mirroring sessions.
|
| const Destinations::iterator dest_it =
|
| @@ -132,7 +153,14 @@ void AudioMirroringManager::InitiateQueriesToFindNewDestination(
|
|
|
| for (Destinations::const_iterator it = sessions_.begin();
|
| it != sessions_.end(); ++it) {
|
| - if (*it != old_destination) {
|
| + if (*it == old_destination)
|
| + continue;
|
| + if ((*it)->IsDuplication()) {
|
| + (*it)->QueryForMatches(
|
| + candidates,
|
| + base::Bind(&AudioMirroringManager::UpdateRoutesToDupDestination,
|
| + base::Unretained(this), *it, true));
|
| + } else {
|
| (*it)->QueryForMatches(
|
| candidates,
|
| base::Bind(&AudioMirroringManager::UpdateRoutesToDestination,
|
| @@ -177,6 +205,34 @@ void AudioMirroringManager::UpdateRoutesToDestination(
|
| InitiateQueriesToFindNewDestination(destination, redivert_candidates);
|
| }
|
|
|
| +void AudioMirroringManager::UpdateRoutesToDupDestination(
|
| + MirroringDestination* destination,
|
| + bool add_only,
|
| + const std::set<SourceFrameRef>& matches) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (std::find(sessions_.begin(), sessions_.end(), destination) ==
|
| + sessions_.end()) {
|
| + return; // Query result callback invoked after StopMirroring().
|
| + }
|
| +
|
| + for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
|
| + if (matches.find(it->source_render_frame) != matches.end()) {
|
| + if (it->dup_destinations.count(destination) == 0) {
|
| + it->dup_destinations[destination] =
|
| + destination->AddPushInput(it->diverter->GetAudioParameters());
|
| + it->diverter->StartDuplicating(it->dup_destinations[destination]);
|
| + }
|
| +
|
| + } else if (!add_only) {
|
| + if (it->dup_destinations.count(destination) > 0) {
|
| + it->diverter->StopDuplicating(it->dup_destinations[destination]);
|
| + it->dup_destinations.erase(destination);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| // static
|
| void AudioMirroringManager::ChangeRoute(
|
| StreamRoutingState* route, MirroringDestination* new_destination) {
|
|
|