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
media / audio / pulse / pulse_loopback_manager.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_AUDIO_PULSE_PULSE_LOOPBACK_MANAGER_H_
#define MEDIA_AUDIO_PULSE_PULSE_LOOPBACK_MANAGER_H_
#include <pulse/pulseaudio.h>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "pulse_loopback.h"
#include <memory>
#include <string>
namespace media {
// This class is required when performing system audio loopback capture. It
// manages PulseLoopbackAudioStreams, which are kind of PulseAudioInputStream
// which is guaranteed to always deliver system audio. There must only be one
// instance of this class associated with a particular pa_context.
class PulseLoopbackManager {
public:
using ReleaseStreamCallback =
base::RepeatingCallback<void(AudioInputStream*)>;
static std::unique_ptr<PulseLoopbackManager> Create(
ReleaseStreamCallback release_stream_callback,
pa_context* context,
pa_threaded_mainloop* mainloop);
~PulseLoopbackManager();
// Creates a new loopback stream, with properties the same as
// AudioDeviceDescription::kLoopbackInputDeviceId.
PulseLoopbackAudioStream* MakeLoopbackStream(
const AudioParameters& params,
AudioManager::LogCallback log_callback,
bool should_mute_system_audio);
// Removes a loopback stream.
void RemoveStream(AudioInputStream* stream);
// Current default sink monitor name.
const std::string& GetLoopbackSourceName();
private:
// Called by PulseAudio when an event occurs. Runs on a PulseAudio thread.
// pa_context_subscribe_cb_t
static void EventCallback(pa_context* context,
pa_subscription_event_type_t type,
uint32_t index,
void* user_data);
PulseLoopbackManager(const std::string& default_monitor_name,
ReleaseStreamCallback release_stream_callback,
pa_context* context,
pa_threaded_mainloop* mainloop);
// Called when either the default sink or source changes.
void OnServerChangeEvent();
// Name of the monitor associated with the current default sink.
std::string default_monitor_name_;
// Passed to newly created streams to be called when they close.
ReleaseStreamCallback release_stream_callback_;
// Global PulseAudio context and mainloop.
const raw_ptr<pa_context> context_;
const raw_ptr<pa_threaded_mainloop> mainloop_;
bool has_muting_loopback_ = false;
// Currently open loopback streams.
std::vector<raw_ptr<PulseLoopbackAudioStream>> streams_;
THREAD_CHECKER(thread_checker_);
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtr<PulseLoopbackManager> weak_this_;
base::WeakPtrFactory<PulseLoopbackManager> weak_ptr_factory_{this};
};
} // namespace media
#endif // MEDIA_AUDIO_PULSE_PULSE_LOOPBACK_MANAGER_H_