forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaudio_renderer_mixer_input.h
142 lines (114 loc) · 5.44 KB
/
audio_renderer_mixer_input.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// THREAD SAFETY
//
// This class is generally not thread safe. Callers should ensure thread safety.
// For instance, the |sink_lock_| in WebAudioSourceProvider synchronizes access
// to this object across the main thread (for WebAudio APIs) and the
// media thread (for HTMLMediaElement APIs).
//
// The one exception is protection for |volume_| via |volume_lock_|. This lock
// prevents races between SetVolume() (called on any thread) and ProvideInput
// (called on audio device thread). See http://crbug.com/588992.
#ifndef MEDIA_BASE_AUDIO_RENDERER_MIXER_INPUT_H_
#define MEDIA_BASE_AUDIO_RENDERER_MIXER_INPUT_H_
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/unguessable_token.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_latency.h"
#include "media/base/audio_renderer_sink.h"
namespace media {
class AudioRendererMixerPool;
class AudioRendererMixer;
class MEDIA_EXPORT AudioRendererMixerInput
: public SwitchableAudioRendererSink,
public AudioConverter::InputCallback {
public:
AudioRendererMixerInput(AudioRendererMixerPool* mixer_pool,
const base::UnguessableToken& owner_token,
const std::string& device_id,
AudioLatency::LatencyType latency);
// SwitchableAudioRendererSink implementation.
void Start() override;
void Stop() override;
void Play() override;
void Pause() override;
void Flush() override;
bool SetVolume(double volume) override;
OutputDeviceInfo GetOutputDeviceInfo() override;
void GetOutputDeviceInfoAsync(OutputDeviceInfoCB info_cb) override;
bool IsOptimizedForHardwareParameters() override;
void Initialize(const AudioParameters& params,
AudioRendererSink::RenderCallback* renderer) override;
void SwitchOutputDevice(const std::string& device_id,
OutputDeviceStatusCB callback) override;
// This is expected to be called on the audio rendering thread. The caller
// must ensure that this input has been added to a mixer before calling the
// function, and that it is not removed from the mixer before this function
// returns.
bool CurrentThreadIsRenderingThread() override;
// Called by AudioRendererMixer when an error occurs.
void OnRenderError();
protected:
~AudioRendererMixerInput() override;
private:
friend class AudioRendererMixerInputTest;
// Pool to obtain mixers from / return them to.
AudioRendererMixerPool* const mixer_pool_;
// Protect |volume_|, accessed by separate threads in ProvideInput() and
// SetVolume().
base::Lock volume_lock_;
bool started_ = false;
bool playing_ = false;
double volume_ GUARDED_BY(volume_lock_) = 1.0;
scoped_refptr<AudioRendererSink> sink_;
base::Optional<OutputDeviceInfo> device_info_;
// AudioConverter::InputCallback implementation.
double ProvideInput(AudioBus* audio_bus, uint32_t frames_delayed) override;
void OnDeviceInfoReceived(OutputDeviceInfoCB info_cb,
OutputDeviceInfo device_info);
// Method to help handle device changes. Must be static to ensure we can still
// execute the |switch_cb| even if the pipeline is destructed. Restarts (if
// necessary) Start() and Play() state with a new |sink| and |device_info|.
//
// |switch_cb| is the callback given to the SwitchOutputDevice() call.
// |sink| is a fresh sink which should be used if device info is good.
// |device_info| is the OutputDeviceInfo for |sink| after
// GetOutputDeviceInfoAsync() completes.
void OnDeviceSwitchReady(OutputDeviceStatusCB switch_cb,
scoped_refptr<AudioRendererSink> sink,
OutputDeviceInfo device_info);
// AudioParameters received during Initialize().
AudioParameters params_;
const base::UnguessableToken owner_token_;
std::string device_id_; // ID of hardware device to use
const AudioLatency::LatencyType latency_;
// AudioRendererMixer obtained from mixer pool during Initialize(),
// guaranteed to live (at least) until it is returned to the pool.
AudioRendererMixer* mixer_ = nullptr;
// Source of audio data which is provided to the mixer.
AudioRendererSink::RenderCallback* callback_ = nullptr;
// SwitchOutputDevice() and GetOutputDeviceInfoAsync() must be mutually
// exclusive when executing; these flags indicate whether one or the other is
// in progress. Each method will use the other method's to defer its action.
bool godia_in_progress_ = false;
bool switch_output_device_in_progress_ = false;
// Set by GetOutputDeviceInfoAsync() if a SwitchOutputDevice() call is in
// progress. GetOutputDeviceInfoAsync() will be invoked again with this value
// once OnDeviceSwitchReady() from the SwitchOutputDevice() call completes.
OutputDeviceInfoCB pending_device_info_cb_;
// Set by SwitchOutputDevice() if a GetOutputDeviceInfoAsync() call is in
// progress. SwitchOutputDevice() will be invoked again with these values once
// the OnDeviceInfoReceived() from the GODIA() call completes.
std::string pending_device_id_;
OutputDeviceStatusCB pending_switch_cb_;
DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerInput);
};
} // namespace media
#endif // MEDIA_BASE_AUDIO_RENDERER_MIXER_INPUT_H_