1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector>
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/synchronization/lock.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/threading/thread_checker.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/time/time.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/common/content_export.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/renderer/media_stream_audio_sink.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/base/audio_converter.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebAudioSourceProvider.h"
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebVector.h"
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace media {
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AudioBus;
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AudioConverter;
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AudioFifo;
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AudioParameters;
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace blink {
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class WebAudioSourceProviderClient;
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace content {
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// WebRtcLocalAudioSourceProvider provides a bridge between classes:
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch//     WebRtcLocalAudioTrack ---> blink::WebAudioSourceProvider
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// WebRtcLocalAudioSourceProvider works as a sink to the WebRtcLocalAudioTrack
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// and store the capture data to a FIFO. When the media stream is connected to
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// WebAudio MediaStreamAudioSourceNode as a source provider,
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// MediaStreamAudioSourceNode will periodically call provideInput() to get the
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// data from the FIFO.
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// All calls are protected by a lock.
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class CONTENT_EXPORT WebRtcLocalAudioSourceProvider
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    :  NON_EXPORTED_BASE(public blink::WebAudioSourceProvider),
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       NON_EXPORTED_BASE(public media::AudioConverter::InputCallback),
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       NON_EXPORTED_BASE(public MediaStreamAudioSink) {
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static const size_t kWebAudioRenderBufferSize;
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  explicit WebRtcLocalAudioSourceProvider(
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      const blink::WebMediaStreamTrack& track);
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual ~WebRtcLocalAudioSourceProvider();
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // MediaStreamAudioSink implementation.
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnData(const int16* audio_data,
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      int sample_rate,
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      int number_of_channels,
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      int number_of_frames) OVERRIDE;
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE;
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void OnReadyStateChanged(
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      blink::WebMediaStreamSource::ReadyState state) OVERRIDE;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // blink::WebAudioSourceProvider implementation.
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void setClient(blink::WebAudioSourceProviderClient* client) OVERRIDE;
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void provideInput(const blink::WebVector<float*>& audio_data,
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                            size_t number_of_frames) OVERRIDE;
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // media::AudioConverter::Inputcallback implementation.
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This function is triggered by provideInput()on the WebAudio audio thread,
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // so it has been under the protection of |lock_|.
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual double ProvideInput(media::AudioBus* audio_bus,
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              base::TimeDelta buffer_delay) OVERRIDE;
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Method to allow the unittests to inject its own sink parameters to avoid
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // query the hardware.
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(xians,tommi): Remove and instead offer a way to inject the sink
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // parameters so that the implementation doesn't rely on the global default
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // hardware config but instead gets the parameters directly from the sink
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // (WebAudio in this case). Ideally the unit test should be able to use that
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // same mechanism to inject the sink parameters for testing.
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void SetSinkParamsForTesting(const media::AudioParameters& sink_params);
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Used to DCHECK that some methods are called on the capture audio thread.
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadChecker capture_thread_checker_;
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<media::AudioConverter> audio_converter_;
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<media::AudioFifo> fifo_;
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<media::AudioBus> input_bus_;
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<media::AudioBus> output_wrapper_;
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool is_enabled_;
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  media::AudioParameters source_params_;
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  media::AudioParameters sink_params_;
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Protects all the member variables above.
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::Lock lock_;
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Used to report the correct delay to |webaudio_source_|.
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::TimeTicks last_fill_;
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The audio track that this source provider is connected to.
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  blink::WebMediaStreamTrack track_;
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Flag to tell if the track has been stopped or not.
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool track_stopped_;
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebRtcLocalAudioSourceProvider);
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace content
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_SOURCE_PROVIDER_H_
114