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 3 // found in the LICENSE file. 4 // 5 // AudioMirroringManager is a singleton object that maintains a set of active 6 // audio mirroring destinations and auto-connects/disconnects audio streams 7 // to/from those destinations. It is meant to be used exclusively on the IO 8 // thread. 9 // 10 // How it works: 11 // 12 // 1. AudioRendererHost gets a CreateStream message from the render process 13 // and, among other things, creates an AudioOutputController to control the 14 // audio data flow between the render and browser processes. More 15 // importantly, it registers the AudioOutputController with 16 // AudioMirroringManager (as a Diverter). 17 // 2. A user request to mirror all the audio for a WebContents is made. A 18 // MirroringDestination is created, and StartMirroring() is called to begin 19 // the mirroring session. The MirroringDestination is queried to determine 20 // which of all the known Diverters will re-route their audio to it. 21 // 3a. During a mirroring session, AudioMirroringManager may encounter new 22 // Diverters, and will query all the MirroringDestinations to determine 23 // which is a match, if any. 24 // 3b. During a mirroring session, a call to StartMirroring() can be made to 25 // request a "refresh" query on a MirroringDestination, and this will 26 // result in AudioMirroringManager starting/stopping only those Diverters 27 // that are not correctly routed to the destination. 28 // 3c. When a mirroring session is stopped, the remaining destinations will be 29 // queried to determine whether diverting should continue to a different 30 // destination. 31 32 #ifndef CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 33 #define CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 34 35 #include <set> 36 #include <utility> 37 #include <vector> 38 39 #include "base/basictypes.h" 40 #include "base/callback_forward.h" 41 #include "base/threading/thread_checker.h" 42 #include "content/common/content_export.h" 43 #include "media/audio/audio_source_diverter.h" 44 45 namespace media { 46 class AudioOutputStream; 47 } 48 49 namespace content { 50 51 class CONTENT_EXPORT AudioMirroringManager { 52 public: 53 // Interface for diverting audio data to an alternative AudioOutputStream. 54 typedef media::AudioSourceDiverter Diverter; 55 56 // A SourceFrameRef is a RenderFrameHost identified by a <render_process_id, 57 // render_frame_id> pair. 58 typedef std::pair<int, int> SourceFrameRef; 59 60 // Interface to be implemented by audio mirroring destinations. See comments 61 // for StartMirroring() and StopMirroring() below. 62 class MirroringDestination { 63 public: 64 // Asynchronously query whether this MirroringDestination wants to consume 65 // audio sourced from each of the |candidates|. |results_callback| is run 66 // to indicate which of them (or none) should have audio routed to this 67 // MirroringDestination. |results_callback| must be run on the same thread 68 // as the one that called QueryForMatches(). 69 typedef base::Callback<void(const std::set<SourceFrameRef>&)> 70 MatchesCallback; 71 virtual void QueryForMatches( 72 const std::set<SourceFrameRef>& candidates, 73 const MatchesCallback& results_callback) = 0; 74 75 // Create a consumer of audio data in the format specified by |params|, and 76 // connect it as an input to mirroring. When Close() is called on the 77 // returned AudioOutputStream, the input is disconnected and the object 78 // becomes invalid. 79 virtual media::AudioOutputStream* AddInput( 80 const media::AudioParameters& params) = 0; 81 82 protected: ~MirroringDestination()83 virtual ~MirroringDestination() {} 84 }; 85 86 // Note: Use GetInstance() for non-test code. 87 AudioMirroringManager(); 88 virtual ~AudioMirroringManager(); 89 90 // Returns the global instance. 91 static AudioMirroringManager* GetInstance(); 92 93 // Add/Remove a diverter for an audio stream with a known RenderFrame source 94 // (represented by |render_process_id| + |render_frame_id|). Multiple 95 // diverters may be added for the same source frame, but never the same 96 // diverter. |diverter| must live until after RemoveDiverter() is called. 97 virtual void AddDiverter(int render_process_id, int render_frame_id, 98 Diverter* diverter); 99 virtual void RemoveDiverter(Diverter* diverter); 100 101 // (Re-)Start/Stop mirroring to the given |destination|. |destination| must 102 // live until after StopMirroring() is called. A client may request a 103 // re-start by calling StartMirroring() again; and this will cause 104 // AudioMirroringManager to query |destination| and only re-route those 105 // diverters that are missing/new to the returned set of matches. 106 virtual void StartMirroring(MirroringDestination* destination); 107 virtual void StopMirroring(MirroringDestination* destination); 108 109 private: 110 friend class AudioMirroringManagerTest; 111 112 struct StreamRoutingState { 113 // The source render frame associated with the audio stream. 114 SourceFrameRef source_render_frame; 115 116 // The diverter for re-routing the audio stream. 117 Diverter* diverter; 118 119 // If not NULL, the audio stream is currently being diverted to this 120 // destination. 121 MirroringDestination* destination; 122 123 StreamRoutingState(const SourceFrameRef& source_frame, 124 Diverter* stream_diverter); 125 ~StreamRoutingState(); 126 }; 127 128 typedef std::vector<StreamRoutingState> StreamRoutes; 129 typedef std::vector<MirroringDestination*> Destinations; 130 131 // Helper to find a destination other than |old_destination| for the given 132 // |candidates| to be diverted to. 133 void InitiateQueriesToFindNewDestination( 134 MirroringDestination* old_destination, 135 const std::set<SourceFrameRef>& candidates); 136 137 // MirroringDestination query callback. |matches| contains all RenderFrame 138 // sources that will be diverted to |destination|. If |add_only| is false, 139 // then any Diverters currently routed to |destination| but not found in 140 // |matches| will be stopped. 141 void UpdateRoutesToDestination(MirroringDestination* destination, 142 bool add_only, 143 const std::set<SourceFrameRef>& matches); 144 145 // Starts diverting audio to the |new_destination|, if not NULL. Otherwise, 146 // stops diverting audio. 147 static void ChangeRoute(StreamRoutingState* route, 148 MirroringDestination* new_destination); 149 150 // Routing table. Contains one entry for each Diverter. 151 StreamRoutes routes_; 152 153 // All active mirroring sessions. 154 Destinations sessions_; 155 156 // Used to check that all AudioMirroringManager code runs on the same thread. 157 base::ThreadChecker thread_checker_; 158 159 DISALLOW_COPY_AND_ASSIGN(AudioMirroringManager); 160 }; 161 162 } // namespace content 163 164 #endif // CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_ 165