1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_capturer_wrapper.h"
17
18 #include "media_log.h"
19 #include "media_errors.h"
20 #include "media_utils.h"
21 #include "ipc_skeleton.h"
22 #include "locale_config.h"
23
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SCREENCAPTURE, "ScreenCaptureACW"};
26 }
27
28 namespace OHOS {
29 namespace Media {
30
OnInterrupt(const InterruptEvent & interruptEvent)31 void AudioCapturerCallbackImpl::OnInterrupt(const InterruptEvent &interruptEvent)
32 {
33 MEDIA_LOGI("AudioCapturerCallbackImpl OnInterrupt hintType:%{public}d, eventType:%{public}d, forceType:%{public}d",
34 interruptEvent.hintType, interruptEvent.eventType, interruptEvent.forceType);
35 }
36
OnStateChange(const CapturerState state)37 void AudioCapturerCallbackImpl::OnStateChange(const CapturerState state)
38 {
39 MEDIA_LOGI("AudioCapturerCallbackImpl OnStateChange state:%{public}d", state);
40 switch (state) {
41 case CAPTURER_PREPARED:
42 MEDIA_LOGD("AudioCapturerCallbackImpl OnStateChange CAPTURER_PREPARED");
43 break;
44 default:
45 MEDIA_LOGD("AudioCapturerCallbackImpl OnStateChange NOT A VALID state");
46 break;
47 }
48 }
49
Start(const OHOS::AudioStandard::AppInfo & appInfo)50 int32_t AudioCapturerWrapper::Start(const OHOS::AudioStandard::AppInfo &appInfo)
51 {
52 std::lock_guard<std::mutex> lock(mutex_);
53 if (isRunning_.load()) {
54 MEDIA_LOGE("Start failed, is running, threadName:%{public}s", threadName_.c_str());
55 return MSERR_UNKNOWN;
56 }
57
58 appInfo_ = appInfo;
59 std::shared_ptr<AudioCapturer> audioCapturer = CreateAudioCapturer(appInfo);
60 CHECK_AND_RETURN_RET_LOG(audioCapturer != nullptr, MSERR_UNKNOWN, "Start failed, create AudioCapturer failed");
61 if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
62 .compare(bundleName_) == 0) {
63 std::vector<SourceType> targetSources = {
64 SourceType::SOURCE_TYPE_MIC,
65 SourceType::SOURCE_TYPE_VOICE_RECOGNITION,
66 SourceType::SOURCE_TYPE_VOICE_MESSAGE
67 };
68 std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
69 if (region == "CN") {
70 targetSources.push_back(SourceType::SOURCE_TYPE_VOICE_COMMUNICATION);
71 }
72 int32_t ret = audioCapturer->SetAudioSourceConcurrency(targetSources);
73 if (ret != MSERR_OK) {
74 MEDIA_LOGE("SetAudioSourceConcurrency failed, ret:%{public}d, threadName:%{public}s", ret,
75 threadName_.c_str());
76 }
77 }
78 if (!audioCapturer->Start()) {
79 MEDIA_LOGE("Start failed, AudioCapturer Start failed, threadName:%{public}s", threadName_.c_str());
80 audioCapturer->Release();
81 audioCapturer = nullptr;
82 OnStartFailed(ScreenCaptureErrorType::SCREEN_CAPTURE_ERROR_INTERNAL, SCREEN_CAPTURE_ERR_UNKNOWN);
83 return MSERR_UNKNOWN;
84 }
85 MEDIA_LOGI("0x%{public}06" PRIXPTR "Start success, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
86
87 isRunning_.store(true);
88 readAudioLoop_ = std::make_unique<std::thread>([this] { this->CaptureAudio(); });
89 audioCapturer_ = audioCapturer;
90 captureState_.store(CAPTURER_RECORDING);
91 return MSERR_OK;
92 }
93
Pause()94 int32_t AudioCapturerWrapper::Pause()
95 {
96 std::lock_guard<std::mutex> lock(mutex_);
97 MEDIA_LOGI("0x%{public}06" PRIXPTR " Pause S, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
98 if (isRunning_.load()) {
99 isRunning_.store(false);
100 if (readAudioLoop_ != nullptr && readAudioLoop_->joinable()) {
101 readAudioLoop_->join();
102 readAudioLoop_.reset();
103 readAudioLoop_ = nullptr;
104 }
105 if (audioCapturer_ != nullptr) {
106 if (!audioCapturer_->Pause()) {
107 MEDIA_LOGE("AudioCapturer Pause failed, threadName:%{public}s", threadName_.c_str());
108 }
109 }
110 }
111 captureState_.store(CAPTURER_PAUSED);
112 MEDIA_LOGI("0x%{public}06" PRIXPTR " Pause E, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
113 return MSERR_OK;
114 }
115
Resume()116 int32_t AudioCapturerWrapper::Resume()
117 {
118 std::lock_guard<std::mutex> lock(mutex_);
119 if (isRunning_.load()) {
120 MEDIA_LOGE("Resume failed, is running, threadName:%{public}s", threadName_.c_str());
121 return MSERR_UNKNOWN;
122 }
123 CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr, MSERR_UNKNOWN, "Resume failed, audioCapturer_ is nullptr");
124
125 if (!audioCapturer_->Start()) {
126 MEDIA_LOGE("AudioCapturer Start failed, threadName:%{public}s", threadName_.c_str());
127 OnStartFailed(ScreenCaptureErrorType::SCREEN_CAPTURE_ERROR_INTERNAL, SCREEN_CAPTURE_ERR_UNKNOWN);
128 return MSERR_UNKNOWN;
129 }
130 MEDIA_LOGI("0x%{public}06" PRIXPTR "Resume success, threadName:%{public}s", FAKE_POINTER(this),
131 threadName_.c_str());
132
133 isRunning_.store(true);
134 readAudioLoop_ = std::make_unique<std::thread>([this] { this->CaptureAudio(); });
135 captureState_.store(CAPTURER_RECORDING);
136 return MSERR_OK;
137 }
138
Stop()139 int32_t AudioCapturerWrapper::Stop()
140 {
141 std::lock_guard<std::mutex> lock(mutex_);
142 MEDIA_LOGI("0x%{public}06" PRIXPTR " Stop S, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
143 isRunning_.store(false);
144 if (readAudioLoop_ != nullptr && readAudioLoop_->joinable()) {
145 readAudioLoop_->join();
146 readAudioLoop_.reset();
147 readAudioLoop_ = nullptr;
148 }
149 if (audioCapturer_ != nullptr) {
150 audioCapturer_->Stop();
151 audioCapturer_->Release();
152 audioCapturer_ = nullptr;
153 }
154 std::unique_lock<std::mutex> bufferLock(bufferMutex_);
155 MEDIA_LOGD("0x%{public}06" PRIXPTR " Stop pop, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
156 while (!availBuffers_.empty()) {
157 if (availBuffers_.front() != nullptr) {
158 free(availBuffers_.front()->buffer);
159 availBuffers_.front()->buffer = nullptr;
160 }
161 availBuffers_.pop();
162 }
163 MEDIA_LOGI("0x%{public}06" PRIXPTR " Stop E, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
164 captureState_.store(CAPTURER_STOPED);
165 return MSERR_OK;
166 }
167
UpdateAudioCapturerConfig(ScreenCaptureContentFilter & filter)168 int32_t AudioCapturerWrapper::UpdateAudioCapturerConfig(ScreenCaptureContentFilter &filter)
169 {
170 MEDIA_LOGI("AudioCapturerWrapper::UpdateAudioCapturerConfig start");
171 contentFilter_ = filter;
172 AudioPlaybackCaptureConfig config;
173 SetInnerStreamUsage(config.filterOptions.usages);
174 if (contentFilter_.filteredAudioContents.find(
175 AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_CURRENT_APP_AUDIO) !=
176 contentFilter_.filteredAudioContents.end()) {
177 config.filterOptions.pids.push_back(appInfo_.appPid);
178 config.filterOptions.pidFilterMode = OHOS::AudioStandard::FilterMode::EXCLUDE;
179 MEDIA_LOGI("UpdateAudioCapturerConfig exclude current app audio");
180 }
181 CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr, MSERR_INVALID_VAL,
182 "AudioCapturerWrapper::UpdateAudioCapturerConfig audioCapturer_ is nullptr");
183 int32_t ret = audioCapturer_->UpdatePlaybackCaptureConfig(config);
184 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL,
185 "AudioCapturerWrapper::UpdateAudioCapturerConfig failed");
186 MEDIA_LOGI("AudioCapturerWrapper::UpdateAudioCapturerConfig success");
187 return MSERR_OK;
188 }
189
GetAudioCapturerState()190 AudioCapturerWrapperState AudioCapturerWrapper::GetAudioCapturerState()
191 {
192 return captureState_.load();
193 }
194
SetInnerStreamUsage(std::vector<OHOS::AudioStandard::StreamUsage> & usages)195 void AudioCapturerWrapper::SetInnerStreamUsage(std::vector<OHOS::AudioStandard::StreamUsage> &usages)
196 {
197 // If do not call this function, the audio framework use MUSIC/MOVIE/GAME/AUDIOBOOK
198 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_MUSIC);
199 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_ALARM);
200 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_MOVIE);
201 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_GAME);
202 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_AUDIOBOOK);
203 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_NAVIGATION);
204 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_UNKNOWN);
205 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VOICE_ASSISTANT);
206 if (contentFilter_.filteredAudioContents.find(
207 AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_NOTIFICATION_AUDIO) ==
208 contentFilter_.filteredAudioContents.end()) {
209 usages.push_back(OHOS::AudioStandard::StreamUsage::STREAM_USAGE_NOTIFICATION);
210 }
211 std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
212 if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
213 .compare(bundleName_) == 0 && region == "CN") {
214 usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION);
215 }
216 }
217
CreateAudioCapturer(const OHOS::AudioStandard::AppInfo & appInfo)218 std::shared_ptr<AudioCapturer> AudioCapturerWrapper::CreateAudioCapturer(const OHOS::AudioStandard::AppInfo &appInfo)
219 {
220 bundleName_ = GetClientBundleName(appInfo.appUid);
221 OHOS::AudioStandard::AppInfo newInfo = appInfo;
222 AudioCapturerOptions capturerOptions;
223 capturerOptions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(audioInfo_.audioSampleRate);
224 capturerOptions.streamInfo.channels = static_cast<AudioChannel>(audioInfo_.audioChannels);
225 capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
226 capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
227 if (audioInfo_.audioSource == AudioCaptureSourceType::SOURCE_DEFAULT ||
228 audioInfo_.audioSource == AudioCaptureSourceType::MIC) {
229 if (isInVoIPCall_.load()) {
230 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_VOICE_COMMUNICATION;
231 } else {
232 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_MIC; // Audio Source Type Mic is 0
233 }
234 } else if (audioInfo_.audioSource == AudioCaptureSourceType::ALL_PLAYBACK ||
235 audioInfo_.audioSource == AudioCaptureSourceType::APP_PLAYBACK) {
236 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_PLAYBACK_CAPTURE;
237 SetInnerStreamUsage(capturerOptions.playbackCaptureConfig.filterOptions.usages);
238 std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
239 if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
240 .compare(bundleName_) == 0 && region == "CN") {
241 newInfo.appTokenId = IPCSkeleton::GetSelfTokenID();
242 newInfo.appFullTokenId = IPCSkeleton::GetSelfTokenID();
243 }
244 }
245 if (contentFilter_.filteredAudioContents.find(
246 AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_CURRENT_APP_AUDIO) !=
247 contentFilter_.filteredAudioContents.end()) {
248 capturerOptions.playbackCaptureConfig.filterOptions.pids.push_back(appInfo.appPid);
249 capturerOptions.playbackCaptureConfig.filterOptions.pidFilterMode =
250 OHOS::AudioStandard::FilterMode::EXCLUDE;
251 MEDIA_LOGI("createAudioCapturer exclude current app audio");
252 }
253 capturerOptions.capturerInfo.capturerFlags = 0;
254 capturerOptions.strategy = { AudioConcurrencyMode::MIX_WITH_OTHERS };
255 std::shared_ptr<AudioCapturer> audioCapturer = AudioCapturer::Create(capturerOptions, newInfo);
256 CHECK_AND_RETURN_RET_LOG(audioCapturer != nullptr, nullptr, "AudioCapturer::Create failed");
257 std::shared_ptr<AudioCapturerCallbackImpl> callback = std::make_shared<AudioCapturerCallbackImpl>();
258 int ret = audioCapturer->SetCapturerCallback(callback);
259 if (ret != MSERR_OK) {
260 audioCapturer->Release();
261 MEDIA_LOGE("SetCapturerCallback failed, threadName:%{public}s", threadName_.c_str());
262 return nullptr;
263 }
264 audioCaptureCallback_ = callback;
265 return audioCapturer;
266 }
267
PartiallyPrintLog(int32_t lineNumber,std::string str)268 void AudioCapturerWrapper::PartiallyPrintLog(int32_t lineNumber, std::string str)
269 {
270 if (captureAudioLogCountMap_.count(lineNumber) == 0) {
271 captureAudioLogCountMap_[lineNumber] = 0;
272 }
273 if (captureAudioLogCountMap_[lineNumber] % AC_LOG_SKIP_NUM == 0) {
274 MEDIA_LOGE("%{public}s", str.c_str());
275 captureAudioLogCountMap_[lineNumber] = 0;
276 }
277 captureAudioLogCountMap_[lineNumber]++;
278 }
279
RelativeSleep(int64_t nanoTime)280 int32_t AudioCapturerWrapper::RelativeSleep(int64_t nanoTime)
281 {
282 int32_t ret = -1; // -1 for bad result.
283 CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
284 "ACW AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
285 struct timespec time;
286 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
287 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
288 clockid_t clockId = CLOCK_MONOTONIC;
289 const int relativeFlag = 0; // flag of relative sleep.
290 ret = clock_nanosleep(clockId, relativeFlag, &time, nullptr);
291 if (ret != 0) {
292 MEDIA_LOGI("ACW RelativeSleep may failed, ret is :%{public}d", ret);
293 }
294 return ret;
295 }
296
CaptureAudio()297 int32_t AudioCapturerWrapper::CaptureAudio()
298 {
299 MEDIA_LOGI("0x%{public}06" PRIXPTR " CaptureAudio S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
300 std::string name = threadName_.substr(0, std::min(threadName_.size(), static_cast<size_t>(MAX_THREAD_NAME_LENGTH)));
301 pthread_setname_np(pthread_self(), name.c_str());
302 size_t bufferLen;
303 CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr && audioCapturer_->GetBufferSize(bufferLen) >= 0,
304 MSERR_NO_MEMORY, "CaptureAudio GetBufferSize failed");
305 Timestamp timestamp;
306 std::shared_ptr<AudioBuffer> audioBuffer;
307 while (true) {
308 CHECK_AND_RETURN_RET_LOG(isRunning_.load(), MSERR_OK, "CaptureAudio is not running, stop capture %{public}s",
309 name.c_str());
310 uint8_t *buffer = static_cast<uint8_t *>(malloc(bufferLen));
311 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, MSERR_OK, "CaptureAudio buffer is no memory, stop capture"
312 " %{public}s", name.c_str());
313 audioBuffer = std::make_shared<AudioBuffer>(buffer, 0, 0, audioInfo_.audioSource);
314 memset_s(audioBuffer->buffer, bufferLen, 0, bufferLen);
315 int32_t bufferRead = audioCapturer_->Read(*(audioBuffer->buffer), bufferLen, true);
316 if (bufferRead <= 0) {
317 RelativeSleep(OHOS::Media::AUDIO_CAPTURE_READ_FAILED_WAIT_TIME);
318 PartiallyPrintLog(__LINE__, "CaptureAudio read audio buffer failed " + name);
319 continue;
320 }
321 audioBuffer->length = bufferRead;
322 audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
323 int64_t audioTime = timestamp.time.tv_nsec + timestamp.time.tv_sec * SEC_TO_NANOSECOND;
324 audioBuffer->timestamp = audioTime;
325 {
326 std::unique_lock<std::mutex> lock(bufferMutex_);
327 CHECK_AND_RETURN_RET_LOG(isRunning_.load(), MSERR_OK, "CaptureAudio is not running, ignore and stop"
328 " %{public}s", name.c_str());
329 if (availBuffers_.size() > MAX_AUDIO_BUFFER_SIZE) {
330 PartiallyPrintLog(__LINE__, "consume slow, drop audio frame" + name);
331 continue;
332 }
333 availBuffers_.push(audioBuffer);
334 }
335 bufferCond_.notify_all();
336 CHECK_AND_RETURN_RET_LOG(isRunning_.load(), MSERR_OK, "CaptureAudio is not running, ignore and stop"
337 " %{public}s", name.c_str());
338 CHECK_AND_RETURN_RET_LOG(screenCaptureCb_ != nullptr, MSERR_OK,
339 "no consumer, will drop audio frame %{public}s", name.c_str());
340 screenCaptureCb_->OnAudioBufferAvailable(true, audioInfo_.audioSource);
341 }
342 MEDIA_LOGI("0x%{public}06" PRIXPTR " CaptureAudio E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
343 return MSERR_OK;
344 }
345
AcquireAudioBuffer(std::shared_ptr<AudioBuffer> & audioBuffer)346 int32_t AudioCapturerWrapper::AcquireAudioBuffer(std::shared_ptr<AudioBuffer> &audioBuffer)
347 {
348 using namespace std::chrono_literals;
349 std::unique_lock<std::mutex> lock(bufferMutex_);
350 CHECK_AND_RETURN_RET_LOG(isRunning_.load(), MSERR_UNKNOWN, "AcquireAudioBuffer failed, not running");
351 MEDIA_LOGD("0x%{public}06" PRIXPTR " Acquire Buffer S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
352
353 if (!bufferCond_.wait_for(lock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS),
354 [this] { return !availBuffers_.empty() || captureState_.load() == CAPTURER_RELEASED; })) {
355 MEDIA_LOGE("AcquireAudioBuffer timeout, threadName:%{public}s", threadName_.c_str());
356 return MSERR_UNKNOWN;
357 }
358 if (availBuffers_.empty()) {
359 MEDIA_LOGE("CAPTURER_RELEASED, threadName:%{public}s", threadName_.c_str());
360 return MSERR_UNKNOWN;
361 }
362 audioBuffer = availBuffers_.front();
363 MEDIA_LOGD("0x%{public}06" PRIXPTR " Acquire Buffer E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
364 return MSERR_OK;
365 }
366
GetBufferSize(size_t & size)367 int32_t AudioCapturerWrapper::GetBufferSize(size_t &size)
368 {
369 using namespace std::chrono_literals;
370 std::unique_lock<std::mutex> lock(bufferMutex_);
371 MEDIA_LOGD("0x%{public}06" PRIXPTR " GetBufferSize Buffer S, name:%{public}s",
372 FAKE_POINTER(this), threadName_.c_str());
373 if (!isRunning_.load()) {
374 MEDIA_LOGD("GetBufferSize failed, not running, name:%{public}s", threadName_.c_str());
375 return MSERR_UNKNOWN;
376 }
377 CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr && audioCapturer_->GetBufferSize(size) >= 0,
378 MSERR_NO_MEMORY, "CaptureAudio GetBufferSize failed");
379 MEDIA_LOGD("0x%{public}06" PRIXPTR " GetBufferSize Buffer E, name:%{public}s",
380 FAKE_POINTER(this), threadName_.c_str());
381 return MSERR_OK;
382 }
383
ReleaseAudioBuffer()384 int32_t AudioCapturerWrapper::ReleaseAudioBuffer()
385 {
386 using namespace std::chrono_literals;
387 std::unique_lock<std::mutex> lock(bufferMutex_);
388 MEDIA_LOGD("0x%{public}06" PRIXPTR " Release Buffer S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
389 CHECK_AND_RETURN_RET_LOG(isRunning_.load(), MSERR_UNKNOWN, "ReleaseAudioBuffer failed, not running");
390 CHECK_AND_RETURN_RET_LOG(!availBuffers_.empty(), MSERR_UNKNOWN, "ReleaseAudioBuffer failed, no frame to release");
391 availBuffers_.pop();
392 MEDIA_LOGD("0x%{public}06" PRIXPTR " Release Buffer E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
393 return MSERR_OK;
394 }
395
SetIsInVoIPCall(bool isInVoIPCall)396 void AudioCapturerWrapper::SetIsInVoIPCall(bool isInVoIPCall)
397 {
398 isInVoIPCall_.store(isInVoIPCall);
399 }
400
OnStartFailed(ScreenCaptureErrorType errorType,int32_t errorCode)401 void AudioCapturerWrapper::OnStartFailed(ScreenCaptureErrorType errorType, int32_t errorCode)
402 {
403 if (screenCaptureCb_ != nullptr) {
404 screenCaptureCb_->OnError(errorType, errorCode);
405 }
406 }
407
~AudioCapturerWrapper()408 AudioCapturerWrapper::~AudioCapturerWrapper()
409 {
410 Stop();
411 captureState_.store(CAPTURER_RELEASED);
412 bufferCond_.notify_all();
413 }
414
OnStartFailed(ScreenCaptureErrorType errorType,int32_t errorCode)415 void MicAudioCapturerWrapper::OnStartFailed(ScreenCaptureErrorType errorType, int32_t errorCode)
416 {
417 (void)errorType;
418 (void)errorCode;
419 if (screenCaptureCb_ != nullptr) {
420 screenCaptureCb_->OnStateChange(AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE);
421 }
422 }
423 } // namespace Media
424 } // namespace OHOS