1 // Copyright (c) 2012 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 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_RESAMPLER_H_
6 #define MEDIA_AUDIO_AUDIO_OUTPUT_RESAMPLER_H_
7 
8 #include "base/containers/flat_map.h"
9 #include "base/macros.h"
10 #include "base/time/time.h"
11 #include "base/timer/timer.h"
12 #include "media/audio/audio_debug_recording_helper.h"
13 #include "media/audio/audio_io.h"
14 #include "media/audio/audio_output_dispatcher.h"
15 #include "media/base/audio_parameters.h"
16 
17 namespace media {
18 
19 class AudioManager;
20 class AudioOutputDispatcherImpl;
21 class OnMoreDataConverter;
22 
23 // AudioOutputResampler is a browser-side resampling and buffering solution
24 // which ensures audio data is always output at given parameters.  See the
25 // AudioConverter class for details on the conversion process.
26 //
27 // AOR works by intercepting the AudioSourceCallback provided to StartStream()
28 // and redirecting it through an AudioConverter instance.
29 //
30 // AOR will automatically fall back from AUDIO_PCM_LOW_LATENCY to
31 // AUDIO_PCM_LINEAR if the output device fails to open at the requested output
32 // parameters. If opening still fails, it will fallback to AUDIO_FAKE.
33 class MEDIA_EXPORT AudioOutputResampler : public AudioOutputDispatcher {
34  public:
35   // Callback type to register an AudioDebugRecorder.
36   using RegisterDebugRecordingSourceCallback =
37       base::RepeatingCallback<std::unique_ptr<AudioDebugRecorder>(
38           const AudioParameters&)>;
39 
40   AudioOutputResampler(AudioManager* audio_manager,
41                        const AudioParameters& input_params,
42                        const AudioParameters& output_params,
43                        const std::string& output_device_id,
44                        base::TimeDelta close_delay,
45                        const RegisterDebugRecordingSourceCallback&
46                            register_debug_recording_source_callback);
47   ~AudioOutputResampler() override;
48 
49   // AudioOutputDispatcher interface.
50   AudioOutputProxy* CreateStreamProxy() override;
51   bool OpenStream() override;
52   bool StartStream(AudioOutputStream::AudioSourceCallback* callback,
53                    AudioOutputProxy* stream_proxy) override;
54   void StopStream(AudioOutputProxy* stream_proxy) override;
55   void StreamVolumeSet(AudioOutputProxy* stream_proxy, double volume) override;
56   void CloseStream(AudioOutputProxy* stream_proxy) override;
57   void FlushStream(AudioOutputProxy* stream_proxy) override;
58 
59  private:
60   using CallbackMap =
61       base::flat_map<AudioOutputProxy*, std::unique_ptr<OnMoreDataConverter>>;
62 
63   // Used to reinitialize |dispatcher_| upon timeout if there are no open
64   // streams.
65   void Reinitialize();
66 
67   // Used to initialize |dispatcher_|.
68   std::unique_ptr<AudioOutputDispatcherImpl> MakeDispatcher(
69       const std::string& output_device_id,
70       const AudioParameters& params);
71 
72   // Stops the stream corresponding to the |item| in |callbacks_|.
73   void StopStreamInternal(const CallbackMap::value_type& item);
74 
75   // Dispatcher to proxy all AudioOutputDispatcher calls too.
76   // Lazily initialized on a first stream open request.
77   std::unique_ptr<AudioOutputDispatcherImpl> dispatcher_;
78 
79   // Map of outstanding OnMoreDataConverter objects.  A new object is created
80   // on every StartStream() call and destroyed on CloseStream().
81   CallbackMap callbacks_;
82 
83   // Used by AudioOutputDispatcherImpl; kept so we can reinitialize on the fly.
84   const base::TimeDelta close_delay_;
85 
86   // Source AudioParameters.
87   const AudioParameters input_params_;
88 
89   // AudioParameters used to setup the output stream; changed upon fallback.
90   AudioParameters output_params_;
91 
92   // The original AudioParameters we were constructed with.
93   const AudioParameters original_output_params_;
94 
95   // Output device id.
96   const std::string device_id_;
97 
98   // The reinitialization timer provides a way to recover from temporary failure
99   // states by clearing the dispatcher if all proxies have been closed and none
100   // have been created within |close_delay_|.  Without this, audio may be lost
101   // to a fake stream indefinitely for transient errors.
102   base::RetainingOneShotTimer reinitialize_timer_;
103 
104   // Callback for registering a debug recording source.
105   RegisterDebugRecordingSourceCallback
106       register_debug_recording_source_callback_;
107 
108   base::WeakPtrFactory<AudioOutputResampler> weak_factory_{this};
109   DISALLOW_COPY_AND_ASSIGN(AudioOutputResampler);
110 };
111 
112 }  // namespace media
113 
114 #endif  // MEDIA_AUDIO_AUDIO_OUTPUT_RESAMPLER_H_
115