Bug 1850460 - Removed file build/build-clang/revert-llvmorg-18-init-3787-gb6a1473f97d...
[gecko.git] / dom / media / CubebInputStream.cpp
blob60eef92fe17b2e3cbcd63c44331fd63cc8a93c4f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
7 #include "CubebInputStream.h"
9 #include "AudioSampleFormat.h"
10 #include "mozilla/Logging.h"
12 namespace mozilla {
14 extern mozilla::LazyLogModule gMediaTrackGraphLog;
16 #ifdef LOG_INTERNAL
17 # undef LOG_INTERNAL
18 #endif // LOG_INTERNAL
19 #define LOG_INTERNAL(level, msg, ...) \
20 MOZ_LOG(gMediaTrackGraphLog, LogLevel::level, (msg, ##__VA_ARGS__))
22 #ifdef LOG
23 # undef LOG
24 #endif // LOG
25 #define LOG(msg, ...) LOG_INTERNAL(Debug, msg, ##__VA_ARGS__)
27 #ifdef LOGE
28 # undef LOGE
29 #endif // LOGE
30 #define LOGE(msg, ...) LOG_INTERNAL(Error, msg, ##__VA_ARGS__)
32 #define InvokeCubebWithLog(func, ...) \
33 ({ \
34 int _retval; \
35 _retval = InvokeCubeb(func, ##__VA_ARGS__); \
36 if (_retval == CUBEB_OK) { \
37 LOG("CubebInputStream %p: %s for stream %p was successful", this, #func, \
38 mStream.get()); \
39 } else { \
40 LOGE("CubebInputStream %p: %s for stream %p was failed. Error %d", this, \
41 #func, mStream.get(), _retval); \
42 } \
43 _retval; \
46 static cubeb_stream_params CreateStreamInitParams(uint32_t aChannels,
47 uint32_t aRate,
48 bool aIsVoice) {
49 cubeb_stream_params params;
50 params.format = CubebUtils::ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
51 params.rate = aRate;
52 params.channels = aChannels;
53 params.layout = CUBEB_LAYOUT_UNDEFINED;
54 params.prefs = CubebUtils::GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_INPUT);
56 if (aIsVoice) {
57 params.prefs |= static_cast<cubeb_stream_prefs>(CUBEB_STREAM_PREF_VOICE);
60 return params;
63 void CubebInputStream::CubebDestroyPolicy::operator()(
64 cubeb_stream* aStream) const {
65 int r = cubeb_stream_register_device_changed_callback(aStream, nullptr);
66 if (r == CUBEB_OK) {
67 LOG("Unregister device changed callback for %p successfully", aStream);
68 } else {
69 LOGE("Fail to unregister device changed callback for %p. Error %d", aStream,
70 r);
72 cubeb_stream_destroy(aStream);
75 /* static */
76 UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
77 uint32_t aChannels,
78 uint32_t aRate,
79 bool aIsVoice,
80 Listener* aListener) {
81 if (!aListener) {
82 LOGE("No available listener");
83 return nullptr;
86 cubeb* context = CubebUtils::GetCubebContext();
87 if (!context) {
88 LOGE("No valid cubeb context");
89 CubebUtils::ReportCubebStreamInitFailure(CubebUtils::GetFirstStream());
90 return nullptr;
93 cubeb_stream_params params =
94 CreateStreamInitParams(aChannels, aRate, aIsVoice);
95 uint32_t latencyFrames = CubebUtils::GetCubebMTGLatencyInFrames(&params);
97 cubeb_stream* cubebStream = nullptr;
99 RefPtr<Listener> listener(aListener);
100 if (int r = CubebUtils::CubebStreamInit(
101 context, &cubebStream, "input-only stream", aDeviceId, &params,
102 nullptr, nullptr, latencyFrames, DataCallback_s, StateCallback_s,
103 listener.get());
104 r != CUBEB_OK) {
105 CubebUtils::ReportCubebStreamInitFailure(CubebUtils::GetFirstStream());
106 LOGE("Fail to create a cubeb stream. Error %d", r);
107 return nullptr;
110 UniquePtr<cubeb_stream, CubebDestroyPolicy> inputStream(cubebStream);
112 LOG("Create a cubeb stream %p successfully", inputStream.get());
114 UniquePtr<CubebInputStream> stream(
115 new CubebInputStream(listener.forget(), std::move(inputStream)));
116 stream->Init();
117 return stream;
120 CubebInputStream::CubebInputStream(
121 already_AddRefed<Listener>&& aListener,
122 UniquePtr<cubeb_stream, CubebDestroyPolicy>&& aStream)
123 : mListener(aListener), mStream(std::move(aStream)) {
124 MOZ_ASSERT(mListener);
125 MOZ_ASSERT(mStream);
128 void CubebInputStream::Init() {
129 // cubeb_stream_register_device_changed_callback is only supported on macOS
130 // platform and MockCubebfor now.
131 InvokeCubebWithLog(cubeb_stream_register_device_changed_callback,
132 CubebInputStream::DeviceChangedCallback_s);
135 int CubebInputStream::Start() { return InvokeCubebWithLog(cubeb_stream_start); }
137 int CubebInputStream::Stop() { return InvokeCubebWithLog(cubeb_stream_stop); }
139 template <typename Function, typename... Args>
140 int CubebInputStream::InvokeCubeb(Function aFunction, Args&&... aArgs) {
141 MOZ_ASSERT(mStream);
142 return aFunction(mStream.get(), std::forward<Args>(aArgs)...);
145 /* static */
146 long CubebInputStream::DataCallback_s(cubeb_stream* aStream, void* aUser,
147 const void* aInputBuffer,
148 void* aOutputBuffer, long aFrames) {
149 MOZ_ASSERT(aUser);
150 MOZ_ASSERT(aInputBuffer);
151 MOZ_ASSERT(!aOutputBuffer);
152 return static_cast<Listener*>(aUser)->DataCallback(aInputBuffer, aFrames);
155 /* static */
156 void CubebInputStream::StateCallback_s(cubeb_stream* aStream, void* aUser,
157 cubeb_state aState) {
158 MOZ_ASSERT(aUser);
159 static_cast<Listener*>(aUser)->StateCallback(aState);
162 /* static */
163 void CubebInputStream::DeviceChangedCallback_s(void* aUser) {
164 MOZ_ASSERT(aUser);
165 static_cast<Listener*>(aUser)->DeviceChangedCallback();
168 #undef LOG_INTERNAL
169 #undef LOG
170 #undef LOGE
172 } // namespace mozilla