• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (IsRecording()) {
54         MEDIA_LOGE("Start failed, is running, threadName:%{public}s", threadName_.c_str());
55         return MSERR_UNKNOWN;
56     }
57 #ifdef SUPPORT_CALL
58     if (isInTelCall_.load()) {
59         MEDIA_LOGE("Start failed, is in telephony call, threadName:%{public}s", threadName_.c_str());
60         return MSERR_UNKNOWN;
61     }
62 #endif
63     appInfo_ = appInfo;
64     std::shared_ptr<AudioCapturer> audioCapturer = CreateAudioCapturer(appInfo);
65     CHECK_AND_RETURN_RET_LOG(audioCapturer != nullptr, MSERR_UNKNOWN, "Start failed, create AudioCapturer failed");
66     if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
67             .compare(bundleName_) == 0) {
68         std::vector<SourceType> targetSources = {
69             SourceType::SOURCE_TYPE_MIC,
70             SourceType::SOURCE_TYPE_VOICE_RECOGNITION,
71             SourceType::SOURCE_TYPE_VOICE_MESSAGE,
72             SourceType::SOURCE_TYPE_CAMCORDER
73         };
74         std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
75         if (region == "CN") {
76             targetSources.push_back(SourceType::SOURCE_TYPE_VOICE_COMMUNICATION);
77         }
78         int32_t ret = audioCapturer->SetAudioSourceConcurrency(targetSources);
79         if (ret != MSERR_OK) {
80             MEDIA_LOGE("SetAudioSourceConcurrency failed, ret:%{public}d, threadName:%{public}s", ret,
81                 threadName_.c_str());
82         }
83     }
84     if (!audioCapturer->Start()) {
85         MEDIA_LOGE("Start failed, AudioCapturer Start failed, threadName:%{public}s", threadName_.c_str());
86         audioCapturer->Release();
87         audioCapturer = nullptr;
88         OnStartFailed(ScreenCaptureErrorType::SCREEN_CAPTURE_ERROR_INTERNAL, SCREEN_CAPTURE_ERR_UNKNOWN);
89         return MSERR_UNKNOWN;
90     }
91     MEDIA_LOGI("0x%{public}06" PRIXPTR "Start success, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
92 
93     audioCapturer_ = audioCapturer;
94     readAudioLoop_ = std::make_unique<std::thread>([this] { this->CaptureAudio(); });
95     captureState_.store(CAPTURER_RECORDING);
96     return MSERR_OK;
97 }
98 
Stop()99 int32_t AudioCapturerWrapper::Stop()
100 {
101     std::lock_guard<std::mutex> lock(mutex_);
102     if (IsStop()) {
103         return MSERR_OK;
104     }
105     captureState_.store(AudioCapturerWrapperState::CAPTURER_STOPPING);
106     MEDIA_LOGI("0x%{public}06" PRIXPTR " Stop S, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
107     if (readAudioLoop_ != nullptr && readAudioLoop_->joinable()) {
108         readAudioLoop_->join();
109         readAudioLoop_.reset();
110         readAudioLoop_ = nullptr;
111     }
112     if (audioCapturer_ != nullptr) {
113         audioCapturer_->Stop();
114         audioCapturer_->Release();
115         audioCapturer_ = nullptr;
116     }
117     std::unique_lock<std::mutex> bufferLock(bufferMutex_);
118     MEDIA_LOGD("0x%{public}06" PRIXPTR " Stop pop, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
119     while (!availBuffers_.empty()) {
120         if (availBuffers_.front() != nullptr) {
121             free(availBuffers_.front()->buffer);
122             availBuffers_.front()->buffer = nullptr;
123         }
124         availBuffers_.pop_front();
125     }
126     MEDIA_LOGI("0x%{public}06" PRIXPTR " Stop E, threadName:%{public}s", FAKE_POINTER(this), threadName_.c_str());
127     captureState_.store(AudioCapturerWrapperState::CAPTURER_STOPED);
128     return MSERR_OK;
129 }
130 
UpdateAudioCapturerConfig(ScreenCaptureContentFilter & filter)131 int32_t AudioCapturerWrapper::UpdateAudioCapturerConfig(ScreenCaptureContentFilter &filter)
132 {
133     MEDIA_LOGI("AudioCapturerWrapper::UpdateAudioCapturerConfig start");
134     contentFilter_ = filter;
135     AudioPlaybackCaptureConfig config;
136     SetInnerStreamUsage(config.filterOptions.usages);
137     if (contentFilter_.filteredAudioContents.find(
138         AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_CURRENT_APP_AUDIO) !=
139         contentFilter_.filteredAudioContents.end()) {
140         config.filterOptions.pids.push_back(appInfo_.appPid);
141         config.filterOptions.pidFilterMode = OHOS::AudioStandard::FilterMode::EXCLUDE;
142         MEDIA_LOGI("UpdateAudioCapturerConfig exclude current app audio");
143     }
144     CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr, MSERR_INVALID_VAL,
145         "AudioCapturerWrapper::UpdateAudioCapturerConfig audioCapturer_ is nullptr");
146     int32_t ret = audioCapturer_->UpdatePlaybackCaptureConfig(config);
147     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL,
148         "AudioCapturerWrapper::UpdateAudioCapturerConfig failed");
149     MEDIA_LOGI("AudioCapturerWrapper::UpdateAudioCapturerConfig success");
150     return MSERR_OK;
151 }
152 
GetAudioCapturerState()153 AudioCapturerWrapperState AudioCapturerWrapper::GetAudioCapturerState()
154 {
155     return captureState_.load();
156 }
157 
SetInnerStreamUsage(std::vector<OHOS::AudioStandard::StreamUsage> & usages)158 void AudioCapturerWrapper::SetInnerStreamUsage(std::vector<OHOS::AudioStandard::StreamUsage> &usages)
159 {
160     // If do not call this function, the audio framework use MUSIC/MOVIE/GAME/AUDIOBOOK
161     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_MUSIC);
162     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_ALARM);
163     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_MOVIE);
164     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_GAME);
165     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_AUDIOBOOK);
166     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_NAVIGATION);
167     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_UNKNOWN);
168     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VOICE_ASSISTANT);
169     usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VOICE_MESSAGE);
170     if (contentFilter_.filteredAudioContents.find(
171         AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_NOTIFICATION_AUDIO) ==
172         contentFilter_.filteredAudioContents.end()) {
173         usages.push_back(OHOS::AudioStandard::StreamUsage::STREAM_USAGE_NOTIFICATION);
174     }
175     std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
176     if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
177             .compare(bundleName_) == 0 && region == "CN") {
178         usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION);
179         usages.push_back(AudioStandard::StreamUsage::STREAM_USAGE_VIDEO_COMMUNICATION);
180     }
181 }
182 
CreateAudioCapturer(const OHOS::AudioStandard::AppInfo & appInfo)183 std::shared_ptr<AudioCapturer> AudioCapturerWrapper::CreateAudioCapturer(const OHOS::AudioStandard::AppInfo &appInfo)
184 {
185     bundleName_ = GetClientBundleName(appInfo.appUid);
186     OHOS::AudioStandard::AppInfo newInfo = appInfo;
187     AudioCapturerOptions capturerOptions;
188     capturerOptions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(audioInfo_.audioSampleRate);
189     capturerOptions.streamInfo.channels = static_cast<AudioChannel>(audioInfo_.audioChannels);
190     capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
191     capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
192     if (audioInfo_.audioSource == AudioCaptureSourceType::SOURCE_DEFAULT ||
193         audioInfo_.audioSource == AudioCaptureSourceType::MIC) {
194         if (isInVoIPCall_.load()) {
195             capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_VOICE_COMMUNICATION;
196         } else {
197             capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_MIC; // Audio Source Type Mic is 0
198         }
199     } else if (audioInfo_.audioSource == AudioCaptureSourceType::ALL_PLAYBACK ||
200         audioInfo_.audioSource == AudioCaptureSourceType::APP_PLAYBACK) {
201         capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_PLAYBACK_CAPTURE;
202         SetInnerStreamUsage(capturerOptions.playbackCaptureConfig.filterOptions.usages);
203         std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
204         if (GetScreenCaptureSystemParam()["const.multimedia.screencapture.screenrecorderbundlename"]
205             .compare(bundleName_) == 0 && region == "CN") {
206             newInfo.appTokenId = IPCSkeleton::GetSelfTokenID();
207             newInfo.appFullTokenId = IPCSkeleton::GetSelfTokenID();
208         }
209     }
210     if (contentFilter_.filteredAudioContents.find(
211         AVScreenCaptureFilterableAudioContent::SCREEN_CAPTURE_CURRENT_APP_AUDIO) !=
212         contentFilter_.filteredAudioContents.end()) {
213         capturerOptions.playbackCaptureConfig.filterOptions.pids.push_back(appInfo.appPid);
214         capturerOptions.playbackCaptureConfig.filterOptions.pidFilterMode =
215             OHOS::AudioStandard::FilterMode::EXCLUDE;
216         MEDIA_LOGI("createAudioCapturer exclude current app audio");
217     }
218     capturerOptions.capturerInfo.capturerFlags = 0;
219     capturerOptions.strategy = { AudioConcurrencyMode::MIX_WITH_OTHERS };
220     std::shared_ptr<AudioCapturer> audioCapturer = AudioCapturer::Create(capturerOptions, newInfo);
221     CHECK_AND_RETURN_RET_LOG(audioCapturer != nullptr, nullptr, "AudioCapturer::Create failed");
222     std::shared_ptr<AudioCapturerCallbackImpl> callback = std::make_shared<AudioCapturerCallbackImpl>();
223     int ret = audioCapturer->SetCapturerCallback(callback);
224     if (ret != MSERR_OK) {
225         audioCapturer->Release();
226         MEDIA_LOGE("SetCapturerCallback failed, threadName:%{public}s", threadName_.c_str());
227         return nullptr;
228     }
229     audioCaptureCallback_ = callback;
230     return audioCapturer;
231 }
232 
PartiallyPrintLog(int32_t lineNumber,std::string str)233 void AudioCapturerWrapper::PartiallyPrintLog(int32_t lineNumber, std::string str)
234 {
235     if (captureAudioLogCountMap_.count(lineNumber) == 0) {
236         captureAudioLogCountMap_[lineNumber] = 0;
237     }
238     if (captureAudioLogCountMap_[lineNumber] % AC_LOG_SKIP_NUM == 0) {
239         MEDIA_LOGE("%{public}s", str.c_str());
240         captureAudioLogCountMap_[lineNumber] = 0;
241     }
242     captureAudioLogCountMap_[lineNumber]++;
243 }
244 
RelativeSleep(int64_t nanoTime)245 int32_t AudioCapturerWrapper::RelativeSleep(int64_t nanoTime)
246 {
247     int32_t ret = -1; // -1 for bad result.
248     CHECK_AND_RETURN_RET_LOG(nanoTime > 0, ret,
249         "ACW AbsoluteSleep invalid sleep time :%{public}" PRId64 " ns", nanoTime);
250     struct timespec time;
251     time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
252     time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND); // Avoids % operation.
253     clockid_t clockId = CLOCK_MONOTONIC;
254     const int relativeFlag = 0; // flag of relative sleep.
255     ret = clock_nanosleep(clockId, relativeFlag, &time, nullptr);
256     if (ret != 0) {
257         MEDIA_LOGI("ACW RelativeSleep may failed, ret is :%{public}d", ret);
258     }
259     return ret;
260 }
261 
GetCaptureAudioBuffer(std::shared_ptr<AudioBuffer> audioBuffer,size_t bufferLen)262 int32_t AudioCapturerWrapper::GetCaptureAudioBuffer(std::shared_ptr<AudioBuffer> audioBuffer, size_t bufferLen)
263 {
264     Timestamp timestamp;
265     memset_s(audioBuffer->buffer, bufferLen, 0, bufferLen);
266     int32_t bufferRead = audioCapturer_->Read(*(audioBuffer->buffer), bufferLen, true);
267     if (bufferRead <= 0) {
268         RelativeSleep(OHOS::Media::AUDIO_CAPTURE_READ_FAILED_WAIT_TIME);
269         PartiallyPrintLog(__LINE__, "CaptureAudio read audio buffer failed " + threadName_ +
270             " ret: " + std::to_string(bufferRead));
271         return MSERR_NO_MEMORY;
272     }
273     audioBuffer->length = bufferRead;
274     bool ret = audioCapturer_->GetTimeStampInfo(timestamp, Timestamp::Timestampbase::MONOTONIC);
275     int64_t audioTime = static_cast<int64_t>(timestamp.time.tv_sec) * AUDIO_NS_PER_SECOND
276         + static_cast<int64_t>(timestamp.time.tv_nsec);
277     if (!ret) {
278         MEDIA_LOGE("0x%{public}06" PRIXPTR " GetTimeStampInfo failed name:%{public}s",
279             FAKE_POINTER(this), threadName_.c_str());
280         return MSERR_NO_MEMORY;
281     }
282     if (audioInfo_.audioSource == AudioCaptureSourceType::SOURCE_DEFAULT ||
283         audioInfo_.audioSource == AudioCaptureSourceType::MIC) {
284         audioBuffer->timestamp = audioTime;
285     } else {
286         audioBuffer->timestamp = audioTime + INNER_AUDIO_READ_TO_HEAR_TIME;
287     }
288     return MSERR_OK;
289 }
290 
SetIsMute(bool isMute)291 void AudioCapturerWrapper::SetIsMute(bool isMute)
292 {
293     isMute_.store(isMute);
294     MEDIA_LOGI("0x%{public}06" PRIXPTR " SetIsMute: %{public}d", FAKE_POINTER(this), isMute_.load());
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 = 0;
303     CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr && audioCapturer_->GetBufferSize(bufferLen) == MSERR_OK &&
304         bufferLen > 0, MSERR_NO_MEMORY, "CaptureAudio GetBufferSize failed");
305     std::shared_ptr<AudioBuffer> audioBuffer;
306     while (true) {
307         CHECK_AND_RETURN_RET_LOG(IsRecording(), MSERR_OK, "CaptureAudio is not running, stop capture %{public}s",
308             name.c_str());
309         uint8_t *buffer = static_cast<uint8_t *>(malloc(bufferLen));
310         CHECK_AND_RETURN_RET_LOG(buffer != nullptr, MSERR_OK, "CaptureAudio buffer is no memory, stop capture"
311             " %{public}s", name.c_str());
312         audioBuffer = std::make_shared<AudioBuffer>(buffer, 0, 0, audioInfo_.audioSource);
313         if (GetCaptureAudioBuffer(audioBuffer, bufferLen) != MSERR_OK) {
314             continue;
315         }
316         {
317             std::unique_lock<std::mutex> lock(bufferMutex_);
318             CHECK_AND_RETURN_RET_LOG(IsRecording(), MSERR_OK, "CaptureAudio is not running, ignore and stop"
319                 " %{public}s", name.c_str());
320             if (availBuffers_.size() > MAX_AUDIO_BUFFER_SIZE) {
321                 PartiallyPrintLog(__LINE__, "consume slow, drop audio frame" + name);
322                 continue;
323             }
324             if (isMute_.load()) {
325                 memset_s(audioBuffer->buffer, bufferLen, 0, bufferLen);
326             }
327             availBuffers_.push_back(audioBuffer);
328         }
329         bufferCond_.notify_all();
330         CHECK_AND_RETURN_RET_LOG(IsRecording(), MSERR_OK, "CaptureAudio is not running, ignore and stop"
331             " %{public}s", name.c_str());
332         CHECK_AND_RETURN_RET_LOG(screenCaptureCb_ != nullptr, MSERR_OK,
333             "no consumer, will drop audio frame %{public}s", name.c_str());
334         screenCaptureCb_->OnAudioBufferAvailable(true, audioInfo_.audioSource);
335         usleep(WRAPPER_PUSH_AUDIO_SAMPLE_INTERVAL_IN_US);
336     }
337     MEDIA_LOGI("0x%{public}06" PRIXPTR " CaptureAudio E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
338     return MSERR_OK;
339 }
340 
UseUpAllLeftBufferUntil(int64_t audioTime)341 int32_t AudioCapturerWrapper::UseUpAllLeftBufferUntil(int64_t audioTime)
342 {
343     using namespace std::chrono_literals;
344     std::unique_lock<std::mutex> lock(bufferMutex_);
345     CHECK_AND_RETURN_RET(IsRecording(), MSERR_OK);
346     MEDIA_LOGD("0x%{public}06" PRIXPTR " UseUpBufUntil S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
347     if (!bufferCond_.wait_for(lock, std::chrono::milliseconds(STOP_WAIT_TIMEOUT_IN_MS),
348         [this, audioTime]() {
349             return availBuffers_.empty() || (availBuffers_.front() != nullptr &&
350                 availBuffers_.front()->timestamp >= audioTime);
351         })) {
352         MEDIA_LOGE("UseUpBufUntil timeout, threadName:%{public}s", threadName_.c_str());
353         return MSERR_UNKNOWN;
354     }
355     if (!availBuffers_.empty() && (availBuffers_.front() != nullptr && availBuffers_.front()->timestamp < audioTime)) {
356         MEDIA_LOGE("UseUpBufUntil not finish all buffer, threadName:%{public}s", threadName_.c_str());
357         return MSERR_UNKNOWN;
358     }
359     MEDIA_LOGD("0x%{public}06" PRIXPTR " UseUpBufUntil E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
360     return MSERR_OK;
361 }
362 
AddBufferFrom(int64_t timeWindow,int64_t bufferSize,int64_t fromTime)363 int32_t AudioCapturerWrapper::AddBufferFrom(int64_t timeWindow, int64_t bufferSize, int64_t fromTime)
364 {
365     using namespace std::chrono_literals;
366     std::unique_lock<std::mutex> lock(bufferMutex_);
367     CHECK_AND_RETURN_RET(IsRecording(), MSERR_OK);
368     CHECK_AND_RETURN_RET_LOG(bufferSize > 0 && bufferSize < MAX_AUDIO_BUFFER_LEN, MSERR_UNKNOWN,
369         "bufferSize invalid %{public}" PRId64, bufferSize);
370     MEDIA_LOGD("0x%{public}06" PRIXPTR " AddBufferFrom S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
371     int32_t diffCount = timeWindow / AUDIO_CAPTURE_READ_FRAME_TIME;
372     MEDIA_LOGI("Audio late, add buffer diffCount: %{public}d", diffCount);
373     while (diffCount > 0) {
374         std::shared_ptr<AudioBuffer> audioBuffer;
375         uint8_t *cacheAudioData = static_cast<uint8_t *>(malloc(bufferSize));
376         CHECK_AND_RETURN_RET_LOG(cacheAudioData != nullptr, MSERR_OK, "AddBuffer cacheAudioData no memory");
377         audioBuffer = std::make_shared<AudioBuffer>(cacheAudioData, 0, 0, audioInfo_.audioSource);
378         memset_s(audioBuffer->buffer, bufferSize, 0, bufferSize);
379         audioBuffer->length = bufferSize;
380         int64_t startTime = fromTime + (diffCount - 1) * AUDIO_CAPTURE_READ_FRAME_TIME;
381         audioBuffer->timestamp = startTime;
382         availBuffers_.push_front(audioBuffer);
383         --diffCount;
384         MEDIA_LOGD("0x%{public}06" PRIXPTR " ABuffer add name:%{public}s time: %{public}" PRId64,
385             FAKE_POINTER(this), threadName_.c_str(), startTime);
386     }
387     MEDIA_LOGD("0x%{public}06" PRIXPTR " AddBufferFrom E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
388     return MSERR_OK;
389 }
390 
DropBufferUntil(int64_t audioTime)391 int32_t AudioCapturerWrapper::DropBufferUntil(int64_t audioTime)
392 {
393     using namespace std::chrono_literals;
394     std::unique_lock<std::mutex> lock(bufferMutex_);
395     CHECK_AND_RETURN_RET(IsRecording(), MSERR_OK);
396     MEDIA_LOGD("0x%{public}06" PRIXPTR " DropBufferUntil S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
397     while (!availBuffers_.empty()) {
398         if (availBuffers_.front() != nullptr && availBuffers_.front()->timestamp < audioTime) {
399             MEDIA_LOGD("0x%{public}06" PRIXPTR " ABuffer drop name:%{public}s time: %{public}" PRId64,
400                 FAKE_POINTER(this), threadName_.c_str(), availBuffers_.front()->timestamp);
401             availBuffers_.pop_front();
402         } else {
403             break;
404         }
405     }
406     MEDIA_LOGD("0x%{public}06" PRIXPTR " DropBufferUntil E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
407     return MSERR_OK;
408 }
409 
GetCurrentAudioTime(int64_t & currentAudioTime)410 int32_t AudioCapturerWrapper::GetCurrentAudioTime(int64_t &currentAudioTime)
411 {
412     struct timespec timestamp = {0, 0};
413     clock_gettime(CLOCK_MONOTONIC, &timestamp);
414     currentAudioTime = static_cast<int64_t>(timestamp.tv_sec) * AUDIO_NS_PER_SECOND
415         + static_cast<int64_t>(timestamp.tv_nsec);
416     MEDIA_LOGD("0x%{public}06" PRIXPTR " GetCurrentAudioTime currentAudioTime:%{public}" PRId64,
417         FAKE_POINTER(this), currentAudioTime);
418     CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr, MSERR_UNKNOWN,
419         "AudioCapturerWrapper::GetCurrentAudioTime audioCapturer is nullptr");
420     return MSERR_OK;
421 }
422 
AcquireAudioBuffer(std::shared_ptr<AudioBuffer> & audioBuffer)423 int32_t AudioCapturerWrapper::AcquireAudioBuffer(std::shared_ptr<AudioBuffer> &audioBuffer)
424 {
425     using namespace std::chrono_literals;
426     std::unique_lock<std::mutex> lock(bufferMutex_);
427     CHECK_AND_RETURN_RET_LOG(IsRecording(), MSERR_UNKNOWN, "AcquireAudioBuffer failed, not running");
428     MEDIA_LOGD("0x%{public}06" PRIXPTR " Acquire Buffer S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
429 
430     if (!bufferCond_.wait_for(lock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS),
431         [this] {
432             return !availBuffers_.empty() || captureState_.load() == AudioCapturerWrapperState::CAPTURER_RELEASED;
433         })) {
434         MEDIA_LOGD("AcquireAudioBuffer timeout, threadName:%{public}s", threadName_.c_str());
435         return MSERR_UNKNOWN;
436     }
437     if (availBuffers_.empty()) {
438         MEDIA_LOGE("CAPTURER_RELEASED, threadName:%{public}s", threadName_.c_str());
439         return MSERR_UNKNOWN;
440     }
441     CHECK_AND_RETURN_RET_LOG(availBuffers_.front() != nullptr, MSERR_UNKNOWN, "AcquireAudioBuffer availBuffers_.front()"
442         " is nullptr %{public}s", threadName_.c_str());
443     audioBuffer = availBuffers_.front();
444     MEDIA_LOGD("0x%{public}06" PRIXPTR " Acquire Buffer E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
445     return MSERR_OK;
446 }
447 
GetBufferSize(size_t & size)448 int32_t AudioCapturerWrapper::GetBufferSize(size_t &size)
449 {
450     using namespace std::chrono_literals;
451     std::unique_lock<std::mutex> lock(bufferMutex_);
452     MEDIA_LOGD("0x%{public}06" PRIXPTR " GetBufferSize Buffer S, name:%{public}s",
453         FAKE_POINTER(this), threadName_.c_str());
454     if (!IsRecording()) {
455         MEDIA_LOGD("GetBufferSize failed, not running, name:%{public}s", threadName_.c_str());
456         return MSERR_UNKNOWN;
457     }
458     CHECK_AND_RETURN_RET_LOG(audioCapturer_ != nullptr && audioCapturer_->GetBufferSize(size) == MSERR_OK,
459         MSERR_NO_MEMORY, "CaptureAudio GetBufferSize failed");
460     MEDIA_LOGD("0x%{public}06" PRIXPTR " GetBufferSize Buffer E, name:%{public}s",
461         FAKE_POINTER(this), threadName_.c_str());
462     return MSERR_OK;
463 }
464 
ReleaseAudioBuffer()465 int32_t AudioCapturerWrapper::ReleaseAudioBuffer()
466 {
467     using namespace std::chrono_literals;
468     std::unique_lock<std::mutex> lock(bufferMutex_);
469     MEDIA_LOGD("0x%{public}06" PRIXPTR " Release Buffer S, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
470     CHECK_AND_RETURN_RET_LOG(IsRecording(), MSERR_UNKNOWN, "ReleaseAudioBuffer failed, not running");
471     CHECK_AND_RETURN_RET_LOG(!availBuffers_.empty(), MSERR_UNKNOWN, "ReleaseAudioBuffer failed, no frame to release");
472     MEDIA_LOGD("0x%{public}06" PRIXPTR " ABuffer release name:%{public}s time: %{public}" PRId64,
473         FAKE_POINTER(this), threadName_.c_str(), availBuffers_.front()->timestamp);
474     availBuffers_.pop_front();
475     MEDIA_LOGD("0x%{public}06" PRIXPTR " Release Buffer E, name:%{public}s", FAKE_POINTER(this), threadName_.c_str());
476     return MSERR_OK;
477 }
478 
SetIsInVoIPCall(bool isInVoIPCall)479 void AudioCapturerWrapper::SetIsInVoIPCall(bool isInVoIPCall)
480 {
481     isInVoIPCall_.store(isInVoIPCall);
482 }
483 
484 #ifdef SUPPORT_CALL
SetIsInTelCall(bool isInTelCall)485 void AudioCapturerWrapper::SetIsInTelCall(bool isInTelCall)
486 {
487     isInTelCall_.store(isInTelCall);
488 }
489 #endif
490 
OnStartFailed(ScreenCaptureErrorType errorType,int32_t errorCode)491 void AudioCapturerWrapper::OnStartFailed(ScreenCaptureErrorType errorType, int32_t errorCode)
492 {
493     if (screenCaptureCb_ != nullptr) {
494         screenCaptureCb_->OnError(errorType, errorCode);
495     }
496 }
497 
~AudioCapturerWrapper()498 AudioCapturerWrapper::~AudioCapturerWrapper()
499 {
500     Stop();
501     captureState_.store(CAPTURER_RELEASED);
502     bufferCond_.notify_all();
503 }
504 
OnStartFailed(ScreenCaptureErrorType errorType,int32_t errorCode)505 void MicAudioCapturerWrapper::OnStartFailed(ScreenCaptureErrorType errorType, int32_t errorCode)
506 {
507     (void)errorType;
508     (void)errorCode;
509     if (screenCaptureCb_ != nullptr) {
510         screenCaptureCb_->OnStateChange(AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE);
511     }
512 }
513 
IsRecording()514 bool AudioCapturerWrapper::IsRecording()
515 {
516     return captureState_.load() == AudioCapturerWrapperState::CAPTURER_RECORDING;
517 }
518 
IsStop()519 bool AudioCapturerWrapper::IsStop()
520 {
521     return captureState_.load() == AudioCapturerWrapperState::CAPTURER_STOPPING ||
522            captureState_.load() == AudioCapturerWrapperState::CAPTURER_STOPED;
523 }
524 } // namespace Media
525 } // namespace OHOS