Chromium Code Reviews| Index: content/renderer/media/media_stream_audio_source.h |
| diff --git a/content/renderer/media/media_stream_audio_source.h b/content/renderer/media/media_stream_audio_source.h |
| index e332b83e0c8fcb51143f42bf8f3cfecba2b92186..b9d8942c44a3728efc2fc536c93ac55463bca709 100644 |
| --- a/content/renderer/media/media_stream_audio_source.h |
| +++ b/content/renderer/media/media_stream_audio_source.h |
| @@ -5,60 +5,180 @@ |
| #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_SOURCE_H_ |
| #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_SOURCE_H_ |
| +#include <vector> |
| + |
| #include "base/compiler_specific.h" |
| #include "base/macros.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/synchronization/lock.h" |
| +#include "base/threading/thread_checker.h" |
| #include "content/common/content_export.h" |
| +#include "content/renderer/media/media_stream_audio_track.h" |
| #include "content/renderer/media/media_stream_source.h" |
| #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
| #include "content/renderer/media/webrtc_audio_capturer.h" |
| +#include "media/base/audio_capturer_source.h" |
| #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" |
| namespace content { |
| +// Represents a source of audio, and manages the delivery of audio data between |
| +// a media::AudioCapturerSource and one or more MediaStreamAudioTracks. There |
| +// are three main use cases, corresponding to the three available constructors: |
| +// |
| +// 1. Null source: Makes this MediaStreamAudioSource a place-holder |
| +// implementation that goes through all the motions, but never transports |
| +// any audio data. |
| +// 2. Local source: Uses content::AudioDeviceFactory to auto-create the |
| +// source, using the parameters and session ID found in StreamDeviceInfo, |
| +// just before the first track is connected. Automatically determines |
| +// whether to transport audio data directly to the tracks, or to instead |
| +// pass it through the WebRTC audio processing pipeline (including |
| +// MediaStreamAudioProcessor). |
| +// 3. Externally-provided local or remote source: Allows users of the public |
| +// content::MediaStreamApi to provide a media::AudioCapturerSource to be |
| +// used as the source of audio data. Audio data is transported directly to |
| +// the tracks (i.e., there is no audio processing). |
| +// |
| +// An instance of this class is owned by blink::WebMediaStreamSource. |
| class CONTENT_EXPORT MediaStreamAudioSource |
|
hubbe
2016/01/28 21:48:13
Would it make sense to write this as an abstract c
miu
2016/01/29 19:43:59
Good point. I'll work on this and ping when ready
|
| - : NON_EXPORTED_BASE(public MediaStreamSource) { |
| + : NON_EXPORTED_BASE(public MediaStreamSource), |
| + NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) { |
| public: |
| - MediaStreamAudioSource(int render_frame_id, |
| - const StreamDeviceInfo& device_info, |
| - const SourceStoppedCallback& stop_callback, |
| - PeerConnectionDependencyFactory* factory); |
| + // Construct a "null" source (as a place-holder, or for testing). |
| MediaStreamAudioSource(); |
| - ~MediaStreamAudioSource() override; |
| - void AddTrack(const blink::WebMediaStreamTrack& track, |
| - const blink::WebMediaConstraints& constraints, |
| - const ConstraintsCallback& callback); |
| + // Construct a local source (e.g., microphone or loopback audio capture) of |
| + // audio, using the audio parameters found in |device_info|. |
| + // |consumer_render_frame_id| references the RenderFrame that will consume the |
| + // audio data. The source is not started until the first call to |
| + // ConnectToTrack(). |
| + MediaStreamAudioSource(int consumer_render_frame_id, |
| + const StreamDeviceInfo& device_info); |
| + |
| + // Construct a source of audio that wraps a media::AudioCapturerSource |
| + // implementation. MediaStreamAudioSource will call the source's Initialize() |
| + // and Start/Stop() methods at some point in the future. Audio will be |
| + // provided in the format specified by |sample_rate|, |channel_layout|, and |
| + // |frames_per_buffer|. |is_remote| must be true if the content is being |
| + // generated from outside of the application (e.g., audio that is being |
| + // streamed from a remote device). The source is not started until the first |
| + // call to ConnectToTrack(). |
| + MediaStreamAudioSource( |
| + const scoped_refptr<media::AudioCapturerSource>& source, |
| + int sample_rate, |
| + media::ChannelLayout channel_layout, |
| + int frames_per_buffer, |
| + bool is_remote); |
| + |
| + ~MediaStreamAudioSource() final; |
| + |
| + // To enable WebRTC-specific audio-processing features, this must be called |
| + // before the first call to ConnectToTrack(). |
| + void set_dependency_factory(PeerConnectionDependencyFactory* factory) { |
| + pc_factory_ = factory; |
| + } |
| + // Connects this source to the given |track|, creating the appropriate |
| + // implementation of the content::MediaStreamAudioTrack interface, which |
| + // becomes associated with and owned by |track|. |constraints| is optional. |
| + // |
| + // Returns true if the source was successfully started and the |
| + // MediaStreamAudioTrack assigned to |track.extraData()|. |
| + bool ConnectToTrack(const blink::WebMediaStreamTrack& track, |
| + const blink::WebMediaConstraints& constraints); |
| + |
| + // Getters/Setters to hold references to objects when the WebRTC audio |
| + // pipeline is being used. |
| void SetLocalAudioSource(webrtc::AudioSourceInterface* source) { |
| local_audio_source_ = source; |
| } |
| - |
| void SetAudioCapturer(const scoped_refptr<WebRtcAudioCapturer>& capturer) { |
| DCHECK(!audio_capturer_.get()); |
| audio_capturer_ = capturer; |
| } |
| - |
| const scoped_refptr<WebRtcAudioCapturer>& GetAudioCapturer() { |
| return audio_capturer_; |
| } |
| - |
| webrtc::AudioSourceInterface* local_audio_source() { |
| return local_audio_source_.get(); |
| } |
| protected: |
| - void DoStopSource() override; |
| + // Called by the superclass to stop whichever source implementation is being |
| + // used. |
| + void DoStopSource() final; |
| private: |
| - const int render_frame_id_; |
| - PeerConnectionDependencyFactory* const factory_; |
| - |
| - // This member holds an instance of webrtc::LocalAudioSource. This is used |
| - // as a container for audio options. |
| + // Implements the MediaStreamAudioTrack interface, providing the functionality |
| + // of adding and removing MediaStreamAudioSinks and delivering audio data to |
| + // each; all in a thread-safe manner. |
| + // |
| + // An instance of this class is owned by blink::WebMediaStreamTrack, but the |
| + // AudioTee holds a weak reference to |this| to notify of its destruction. |
| + class AudioTee; |
| + |
| + // Determines whether the default audio pipeline or the WebRTC audio pipeline |
| + // will be used, and then starts the appropriate source for that pipeline if |
| + // needed. Returns true if the source was successfully started and |
| + // MediaStreamAudioTracks can be created and connected to it. |
| + bool EnsureSourceIsStarted(const blink::WebMediaConstraints& constraints); |
| + void StartDefaultPipeline(); |
| + void StartWebRtcPipeline(const blink::WebMediaConstraints& constraints); |
| + |
| + // Removes |tee| from the list of instances that get a copy of the source |
| + // audio data. |
| + void StopAudioDeliveryTo(AudioTee* tee); |
| + |
| + // media::AudioCapturerSource::CaptureCallback implementation. |
| + void Capture(const media::AudioBus* audio_bus, |
| + int audio_delay_milliseconds, |
| + double volume, |
| + bool key_pressed) final; |
| + void OnCaptureError(const std::string& message) final; |
| + |
| + // The audio parameters to use for |source_|. |
| + const media::AudioParameters params_; |
| + |
| + // True if |source_| provides audio data from a remote application. |
| + const bool is_remote_; |
| + |
| + // Used when creating AudioInputDevices via the AudioDeviceFactory. |
| + const int consumer_render_frame_id_; |
| + |
| + // The current state of this source. |
| + enum { |
| + NULL_SOURCE_NOT_STARTED, // This instance is a "null" audio source. |
|
hubbe
2016/01/28 21:48:13
I'm not a big fan of using different states for di
|
| + INPUT_DEVICE_NOT_STARTED, // AudioInputDevice not started yet. |
| + SOURCE_NOT_STARTED, // Source provided via ctor not started yet. |
| + STARTED_DEFAULT_PIPELINE, // Started, this instance delivers audio. |
| + STARTED_WEBRTC_PIPELINE, // Started, but using WebRTC audio pipeline. |
| + STOPPED, // Source stopped. |
| + } current_state_; |
| + |
| + // This is lazy-instantiated on the first call to EnsureSourceIsStarted(). |
| + scoped_refptr<media::AudioCapturerSource> source_; |
| + |
| + // List of currently-connected AudioTees. This is empty when using the |
| + // WebRTC audio pipeline. While MediaStreamAudioSource creates these |
| + // instances, blink::WebMediaStreamTrack instances own the objects. |
| + std::vector<AudioTee*> audio_tees_; |
| + base::Lock lock_; // Protects concurrent access to |audio_tees_|. |
| + |
| + // References to WebRTC audio pipeline objects. These are null, if not |
| + // applicable. |
| + PeerConnectionDependencyFactory* pc_factory_; // May be null, if unused. |
| scoped_refptr<webrtc::AudioSourceInterface> local_audio_source_; |
| - |
| scoped_refptr<WebRtcAudioCapturer> audio_capturer_; |
| + // In debug builds, check that all methods that could cause object graph |
| + // or data flow changes are being called on the same thread. |
| + base::ThreadChecker thread_checker_; |
| + |
| + // Provides weak pointers so that AudioTees can call StopAudioDeliveryTo() |
| + // safely. |
| + base::WeakPtrFactory<MediaStreamAudioSource> weak_factory_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioSource); |
| }; |