12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AudioMirroringManager is a singleton object that maintains a set of active 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// audio mirroring destinations and auto-connects/disconnects audio streams 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to/from those destinations. It is meant to be used exclusively on the IO 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// thread. 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// How it works: 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. AudioRendererHost gets a CreateStream message from the render process 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and, among other things, creates an AudioOutputController to control the 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// audio data flow between the render and browser processes. More 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// importantly, it registers the AudioOutputController with 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// AudioMirroringManager (as a Diverter). 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 2. A user request to mirror all the audio for a WebContents is made. A 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// MirroringDestination is created, and StartMirroring() is called to begin 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the mirroring session. The MirroringDestination is queried to determine 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// which of all the known Diverters will re-route their audio to it. 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 3a. During a mirroring session, AudioMirroringManager may encounter new 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Diverters, and will query all the MirroringDestinations to determine 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// which is a match, if any. 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 3b. During a mirroring session, a call to StartMirroring() can be made to 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// request a "refresh" query on a MirroringDestination, and this will 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// result in AudioMirroringManager starting/stopping only those Diverters 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// that are not correctly routed to the destination. 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 3c. When a mirroring session is stopped, the remaining destinations will be 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// queried to determine whether diverting should continue to a different 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// destination. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <set> 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility> 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector> 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_forward.h" 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/threading/thread_checker.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_source_diverter.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioOutputStream; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT AudioMirroringManager { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Interface for diverting audio data to an alternative AudioOutputStream. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef media::AudioSourceDiverter Diverter; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // A SourceFrameRef is a RenderFrameHost identified by a <render_process_id, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // render_frame_id> pair. 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef std::pair<int, int> SourceFrameRef; 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Interface to be implemented by audio mirroring destinations. See comments 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for StartMirroring() and StopMirroring() below. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class MirroringDestination { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Asynchronously query whether this MirroringDestination wants to consume 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // audio sourced from each of the |candidates|. |results_callback| is run 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to indicate which of them (or none) should have audio routed to this 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // MirroringDestination. |results_callback| must be run on the same thread 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // as the one that called QueryForMatches(). 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef base::Callback<void(const std::set<SourceFrameRef>&)> 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MatchesCallback; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void QueryForMatches( 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::set<SourceFrameRef>& candidates, 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MatchesCallback& results_callback) = 0; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a consumer of audio data in the format specified by |params|, and 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connect it as an input to mirroring. When Close() is called on the 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned AudioOutputStream, the input is disconnected and the object 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // becomes invalid. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual media::AudioOutputStream* AddInput( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const media::AudioParameters& params) = 0; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~MirroringDestination() {} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Note: Use GetInstance() for non-test code. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioMirroringManager(); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~AudioMirroringManager(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns the global instance. 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static AudioMirroringManager* GetInstance(); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Add/Remove a diverter for an audio stream with a known RenderFrame source 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // (represented by |render_process_id| + |render_frame_id|). Multiple 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // diverters may be added for the same source frame, but never the same 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // diverter. |diverter| must live until after RemoveDiverter() is called. 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void AddDiverter(int render_process_id, int render_frame_id, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Diverter* diverter); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void RemoveDiverter(Diverter* diverter); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // (Re-)Start/Stop mirroring to the given |destination|. |destination| must 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // live until after StopMirroring() is called. A client may request a 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // re-start by calling StartMirroring() again; and this will cause 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // AudioMirroringManager to query |destination| and only re-route those 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // diverters that are missing/new to the returned set of matches. 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void StartMirroring(MirroringDestination* destination); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void StopMirroring(MirroringDestination* destination); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci friend class AudioMirroringManagerTest; 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct StreamRoutingState { 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The source render frame associated with the audio stream. 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SourceFrameRef source_render_frame; 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The diverter for re-routing the audio stream. 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Diverter* diverter; 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If not NULL, the audio stream is currently being diverted to this 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // destination. 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MirroringDestination* destination; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StreamRoutingState(const SourceFrameRef& source_frame, 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Diverter* stream_diverter); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~StreamRoutingState(); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef std::vector<StreamRoutingState> StreamRoutes; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef std::vector<MirroringDestination*> Destinations; 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Helper to find a destination other than |old_destination| for the given 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |candidates| to be diverted to. 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void InitiateQueriesToFindNewDestination( 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MirroringDestination* old_destination, 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::set<SourceFrameRef>& candidates); 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // MirroringDestination query callback. |matches| contains all RenderFrame 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // sources that will be diverted to |destination|. If |add_only| is false, 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // then any Diverters currently routed to |destination| but not found in 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |matches| will be stopped. 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void UpdateRoutesToDestination(MirroringDestination* destination, 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool add_only, 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::set<SourceFrameRef>& matches); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Starts diverting audio to the |new_destination|, if not NULL. Otherwise, 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // stops diverting audio. 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static void ChangeRoute(StreamRoutingState* route, 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MirroringDestination* new_destination); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Routing table. Contains one entry for each Diverter. 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StreamRoutes routes_; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // All active mirroring sessions. 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Destinations sessions_; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Used to check that all AudioMirroringManager code runs on the same thread. 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ThreadChecker thread_checker_; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioMirroringManager); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 165