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