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 ¤tAudioTime)
411 {
412 struct timespec timestamp = {0, 0};
413 clock_gettime(CLOCK_MONOTONIC, ×tamp);
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