1 /*
2 * Copyright (c) 2023-2023 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 #include "audio_capture_module.h"
16 #include "common/log.h"
17 #include "osal/task/autolock.h"
18 #include "common/status.h"
19 #include "audio_type_translate.h"
20 #include "audio_capturer.h"
21 #include "avcodec_sysevent.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_RECORDER, "HiStreamer" };
25 }
26
27 namespace OHOS {
28 namespace Media {
29 namespace AudioCaptureModule {
30 using namespace OHOS::MediaAVCodec;
31 #define FAIL_LOG_RETURN(exec, msg) \
32 do { \
33 auto ret = (exec); \
34 if (ret != 0) { \
35 MEDIA_LOG_E(msg " failed return " PUBLIC_LOG_D32, ret); \
36 return Error2Status(ret); \
37 } \
38 } while (0)
39
40 constexpr size_t MAX_CAPTURE_BUFFER_SIZE = 100000;
41
42 class AudioCapturerCallbackImpl : public AudioStandard::AudioCapturerCallback {
43 public:
AudioCapturerCallbackImpl(std::shared_ptr<AudioCaptureModuleCallback> audioCaptureModuleCallback)44 explicit AudioCapturerCallbackImpl(std::shared_ptr<AudioCaptureModuleCallback> audioCaptureModuleCallback)
45 : audioCaptureModuleCallback_(audioCaptureModuleCallback)
46 {
47 }
48
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)49 void OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent) override
50 {
51 MEDIA_LOG_E("AudioCapture OnInterrupt Hint: " PUBLIC_LOG_D32 ", EventType: " PUBLIC_LOG_D32 ", forceType: "
52 PUBLIC_LOG_D32, interruptEvent.hintType, interruptEvent.eventType, interruptEvent.forceType);
53 if (audioCaptureModuleCallback_ != nullptr) {
54 MEDIA_LOG_I("audioCaptureModuleCallback_ send info to audioCaptureFilter");
55 audioCaptureModuleCallback_->OnInterrupt("AudioCapture OnInterrupt");
56 }
57 }
58
OnStateChange(const AudioStandard::CapturerState state)59 void OnStateChange(const AudioStandard::CapturerState state) override
60 {
61 }
62
63 private:
64 std::shared_ptr<AudioCaptureModuleCallback> audioCaptureModuleCallback_;
65 };
66
AudioCaptureModule()67 AudioCaptureModule::AudioCaptureModule()
68 {
69 }
70
~AudioCaptureModule()71 AudioCaptureModule::~AudioCaptureModule()
72 {
73 DoDeinit();
74 }
75
Init()76 Status AudioCaptureModule::Init()
77 {
78 AutoLock lock(captureMutex_);
79 if (audioCapturer_ == nullptr) {
80 AudioStandard::AppInfo appInfo;
81 appInfo.appTokenId = static_cast<uint32_t>(appTokenId_);
82 appInfo.appUid = appUid_;
83 appInfo.appPid = appPid_;
84 appInfo.appFullTokenId = static_cast<uint64_t>(appFullTokenId_);
85 audioCapturer_ = AudioStandard::AudioCapturer::Create(options_, appInfo);
86 if (audioCapturer_ == nullptr) {
87 MEDIA_LOG_E("Create audioCapturer fail");
88 SetFaultEvent("AudioCaptureModule::Init, create audioCapturer fail");
89 return Status::ERROR_UNKNOWN;
90 }
91 audioInterruptCallback_ = std::make_shared<AudioCapturerCallbackImpl>(audioCaptureModuleCallback_);
92 audioCapturer_->SetCapturerCallback(audioInterruptCallback_);
93 }
94 return Status::OK;
95 }
96
DoDeinit()97 Status AudioCaptureModule::DoDeinit()
98 {
99 AutoLock lock(captureMutex_);
100 if (audioCapturer_) {
101 if (audioCapturer_->GetStatus() == AudioStandard::CapturerState::CAPTURER_RUNNING) {
102 FALSE_LOG_MSG(audioCapturer_->Stop(), "stop audioCapturer fail");
103 }
104 FALSE_LOG_MSG(audioCapturer_->Release(), "Release audioCapturer fail");
105 audioCapturer_->RemoveAudioCapturerInfoChangeCallback(audioCapturerInfoChangeCallback_);
106 audioCapturer_ = nullptr;
107 }
108 return Status::OK;
109 }
110
Deinit()111 Status AudioCaptureModule::Deinit()
112 {
113 MEDIA_LOG_I("Deinit");
114 return DoDeinit();
115 }
116
Prepare()117 Status AudioCaptureModule::Prepare()
118 {
119 MEDIA_LOG_I("Prepare enter.");
120 size_t size;
121 {
122 AutoLock lock (captureMutex_);
123 FALSE_RETURN_V_MSG_E(audioCapturer_ != nullptr, Status::ERROR_WRONG_STATE, "no available audio capture");
124 FAIL_LOG_RETURN(audioCapturer_->GetBufferSize(size), "audioCapturer GetBufferSize");
125 }
126 FALSE_RETURN_V_MSG_E(size < MAX_CAPTURE_BUFFER_SIZE, Status::ERROR_INVALID_PARAMETER,
127 "bufferSize is too big: " PUBLIC_LOG_ZU, size);
128 bufferSize_ = size;
129 MEDIA_LOG_E("bufferSize is: " PUBLIC_LOG_ZU, bufferSize_);
130 return Status::OK;
131 }
132
Reset()133 Status AudioCaptureModule::Reset()
134 {
135 MEDIA_LOG_I("Reset enter.");
136 {
137 AutoLock lock (captureMutex_);
138 FALSE_RETURN_V_MSG_E(audioCapturer_ != nullptr, Status::ERROR_WRONG_STATE, "no available audio capture");
139 if (audioCapturer_->GetStatus() == AudioStandard::CapturerState::CAPTURER_RUNNING) {
140 FALSE_LOG_MSG(audioCapturer_->Stop(), "Stop audioCapturer fail");
141 }
142 }
143 bufferSize_ = 0;
144 bitRate_ = 0;
145 options_ = AudioStandard::AudioCapturerOptions();
146 return Status::OK;
147 }
148
Start()149 Status AudioCaptureModule::Start()
150 {
151 MEDIA_LOG_I("start enter.");
152 AutoLock lock (captureMutex_);
153 FALSE_RETURN_V_MSG_E(audioCapturer_ != nullptr, Status::ERROR_WRONG_STATE, "no available audio capture");
154 if (audioCapturer_->GetStatus() != AudioStandard::CapturerState::CAPTURER_RUNNING) {
155 if (!audioCapturer_->Start()) {
156 MEDIA_LOG_E("audioCapturer start failed");
157 SetFaultEvent("AudioCaptureModule::Start error");
158 return Status::ERROR_UNKNOWN;
159 }
160 }
161 isTrackMaxAmplitude = false;
162 return Status::OK;
163 }
164
Stop()165 Status AudioCaptureModule::Stop()
166 {
167 MEDIA_LOG_I("stop enter.");
168 AutoLock lock (captureMutex_);
169 if (audioCapturer_ && audioCapturer_->GetStatus() == AudioStandard::CAPTURER_RUNNING) {
170 if (!audioCapturer_->Stop()) {
171 MEDIA_LOG_E("Stop audioCapturer fail");
172 SetFaultEvent("AudioCaptureModule::Stop error");
173 return Status::ERROR_UNKNOWN;
174 }
175 }
176 return Status::OK;
177 }
178
GetParameter(std::shared_ptr<Meta> & meta)179 Status AudioCaptureModule::GetParameter(std::shared_ptr<Meta> &meta)
180 {
181 MEDIA_LOG_I("GetParameter enter.");
182 AudioStandard::AudioCapturerParams params;
183 {
184 AutoLock lock (captureMutex_);
185 if (!audioCapturer_) {
186 return Status::ERROR_WRONG_STATE;
187 }
188 FAIL_LOG_RETURN(audioCapturer_->GetParams(params), "audioCapturer GetParams");
189 }
190
191 if (params.samplingRate != options_.streamInfo.samplingRate) {
192 MEDIA_LOG_W("samplingRate has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
193 options_.streamInfo.samplingRate, params.samplingRate);
194 }
195 FALSE_LOG(meta->Set<Tag::AUDIO_SAMPLE_RATE>(params.samplingRate));
196
197 if (params.audioChannel != options_.streamInfo.channels) {
198 MEDIA_LOG_W("audioChannel has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
199 options_.streamInfo.channels, params.audioChannel);
200 }
201 FALSE_LOG(meta->Set<Tag::AUDIO_CHANNEL_COUNT>(params.audioChannel));
202
203 if (params.audioSampleFormat != options_.streamInfo.format) {
204 MEDIA_LOG_W("audioSampleFormat has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
205 options_.streamInfo.format, params.audioSampleFormat);
206 }
207 FALSE_LOG(meta->Set<Tag::AUDIO_SAMPLE_FORMAT>(static_cast<Plugins::AudioSampleFormat>(params.audioSampleFormat)));
208
209 meta->Set<Tag::MEDIA_BITRATE>(bitRate_);
210 return Status::OK;
211 }
212
SetParameter(const std::shared_ptr<Meta> & meta)213 Status AudioCaptureModule::SetParameter(const std::shared_ptr<Meta> &meta)
214 {
215 FALSE_LOG_MSG(meta->Get<Tag::APP_TOKEN_ID>(appTokenId_), "Unknown APP_TOKEN_ID");
216 FALSE_LOG_MSG(meta->Get<Tag::APP_UID>(appUid_), "Unknown APP_UID");
217 FALSE_LOG_MSG(meta->Get<Tag::APP_PID>(appPid_), "Unknown APP_PID");
218 FALSE_LOG_MSG(meta->Get<Tag::APP_FULL_TOKEN_ID>(appFullTokenId_), "Unknown appFullTokenId_");
219 FALSE_LOG_MSG(meta->Get<Tag::MEDIA_BITRATE>(bitRate_), "Unknown MEDIA_BITRATE");
220
221 int32_t sampleRate = 0;
222 if (meta->Get<Tag::AUDIO_SAMPLE_RATE>(sampleRate)) {
223 FALSE_RETURN_V_MSG_E(AssignSampleRateIfSupported(sampleRate), Status::ERROR_INVALID_PARAMETER,
224 "SampleRate is unsupported by audiocapturer");
225 }
226
227 int32_t channelCount = 0;
228 if (meta->Get<Tag::AUDIO_CHANNEL_COUNT>(channelCount)) {
229 FALSE_RETURN_V_MSG_E(AssignChannelNumIfSupported(channelCount), Status::ERROR_INVALID_PARAMETER,
230 "ChannelNum is unsupported by audiocapturer");
231 }
232
233 Plugins::AudioSampleFormat sampleFormat;
234 if (meta->Get<Tag::AUDIO_SAMPLE_FORMAT>(sampleFormat)) {
235 FALSE_RETURN_V_MSG_E(AssignSampleFmtIfSupported(static_cast<Plugins::AudioSampleFormat>(sampleFormat)),
236 Status::ERROR_INVALID_PARAMETER, "SampleFormat is unsupported by audiocapturer");
237 }
238
239 AudioStandard::AudioEncodingType audioEncoding = AudioStandard::ENCODING_INVALID;
240 auto supportedEncodingTypes = OHOS::AudioStandard::AudioCapturer::GetSupportedEncodingTypes();
241 for (auto& supportedEncodingType : supportedEncodingTypes) {
242 if (supportedEncodingType == AudioStandard::ENCODING_PCM) {
243 audioEncoding = AudioStandard::ENCODING_PCM;
244 break;
245 }
246 }
247
248 if (audioEncoding != AudioStandard::ENCODING_PCM) {
249 MEDIA_LOG_E("audioCapturer do not support pcm encoding");
250 SetFaultEvent("AudioCaptureModule::Prepare, audioCapturer do not support pcm encoding");
251 return Status::ERROR_UNKNOWN;
252 }
253 options_.streamInfo.encoding = AudioStandard::ENCODING_PCM;
254 return Status::OK;
255 }
256
AssignSampleRateIfSupported(const int32_t value)257 bool AudioCaptureModule::AssignSampleRateIfSupported(const int32_t value)
258 {
259 uint32_t sampleRate = static_cast<uint32_t>(value);
260 AudioStandard::AudioSamplingRate aRate = AudioStandard::SAMPLE_RATE_8000;
261 FALSE_RETURN_V_MSG_E(SampleRateNum2Enum(sampleRate, aRate), false, "sample rate " PUBLIC_LOG_U32
262 "not supported", sampleRate);
263 for (const auto& rate : AudioStandard::AudioCapturer::GetSupportedSamplingRates()) {
264 if (rate == sampleRate) {
265 options_.streamInfo.samplingRate = rate;
266 return true;
267 }
268 }
269 return false;
270 }
271
AssignChannelNumIfSupported(const int32_t value)272 bool AudioCaptureModule::AssignChannelNumIfSupported(const int32_t value)
273 {
274 uint32_t channelNum = static_cast<uint32_t>(value);
275 constexpr uint32_t maxSupportChannelNum = 2;
276 if (channelNum > maxSupportChannelNum) {
277 MEDIA_LOG_E("Unsupported channelNum: " PUBLIC_LOG_U32, channelNum);
278 return false;
279 }
280 AudioStandard::AudioChannel aChannel = AudioStandard::MONO;
281 FALSE_RETURN_V_MSG_E(ChannelNumNum2Enum(channelNum, aChannel), false, "Channel num "
282 PUBLIC_LOG_U32 "not supported", channelNum);
283 for (const auto& channel : AudioStandard::AudioCapturer::GetSupportedChannels()) {
284 if (channel == channelNum) {
285 options_.streamInfo.channels = channel;
286 return true;
287 }
288 }
289 return false;
290 }
291
AssignSampleFmtIfSupported(const Plugins::AudioSampleFormat value)292 bool AudioCaptureModule::AssignSampleFmtIfSupported(const Plugins::AudioSampleFormat value)
293 {
294 Plugins::AudioSampleFormat sampleFormat = value;
295 AudioStandard::AudioSampleFormat aFmt = AudioStandard::AudioSampleFormat::INVALID_WIDTH;
296 FALSE_RETURN_V_MSG_E(ModuleFmt2SampleFmt(sampleFormat, aFmt), false,
297 "sample format " PUBLIC_LOG_U8 " not supported", static_cast<uint8_t>(sampleFormat));
298 for (const auto& fmt : AudioStandard::AudioCapturer::GetSupportedFormats()) {
299 if (fmt == aFmt) {
300 options_.streamInfo.format = fmt;
301 return true;
302 }
303 }
304 return false;
305 }
306
Read(std::shared_ptr<AVBuffer> & buffer,size_t expectedLen)307 Status AudioCaptureModule::Read(std::shared_ptr<AVBuffer> &buffer, size_t expectedLen)
308 {
309 MEDIA_LOG_D("AudioCaptureModule Read");
310 auto bufferMeta = buffer->meta_;
311 if (!bufferMeta) {
312 return Status::ERROR_INVALID_PARAMETER;
313 }
314 std::shared_ptr<AVMemory> bufData = buffer->memory_;
315 if (bufData->GetCapacity() <= 0) {
316 return Status::ERROR_NO_MEMORY;
317 }
318 auto size = 0;
319 Status ret = Status::OK;
320 {
321 AutoLock lock(captureMutex_);
322 if (audioCapturer_ == nullptr) {
323 MEDIA_LOG_E("Audio capture is null");
324 return Status::ERROR_WRONG_STATE;
325 }
326 if (audioCapturer_->GetStatus() != AudioStandard::CAPTURER_RUNNING) {
327 return Status::ERROR_AGAIN;
328 }
329 size = audioCapturer_->Read(*bufData->GetAddr(), expectedLen, true);
330 }
331 FALSE_RETURN_V_MSG_E(size >= 0, Status::ERROR_NOT_ENOUGH_DATA, "audioCapturer Read() fail");
332
333 if (isTrackMaxAmplitude) {
334 TrackMaxAmplitude((int16_t *)bufData->GetAddr(),
335 static_cast<int32_t>(static_cast<uint32_t>(bufData->GetSize()) >> 1));
336 }
337 return ret;
338 }
339
GetSize(uint64_t & size)340 Status AudioCaptureModule::GetSize(uint64_t& size)
341 {
342 if (bufferSize_ == 0) {
343 return Status::ERROR_INVALID_PARAMETER;
344 }
345 size = bufferSize_;
346 return Status::OK;
347 }
348
SetAudioInterruptListener(const std::shared_ptr<AudioCaptureModuleCallback> & callback)349 Status AudioCaptureModule::SetAudioInterruptListener(const std::shared_ptr<AudioCaptureModuleCallback> &callback)
350 {
351 if (callback == nullptr) {
352 MEDIA_LOG_E("SetAudioInterruptListener callback input param is nullptr");
353 return Status::ERROR_INVALID_PARAMETER;
354 }
355 audioCaptureModuleCallback_ = callback;
356 return Status::OK;
357 }
358
SetAudioCapturerInfoChangeCallback(const std::shared_ptr<AudioStandard::AudioCapturerInfoChangeCallback> & callback)359 Status AudioCaptureModule::SetAudioCapturerInfoChangeCallback(
360 const std::shared_ptr<AudioStandard::AudioCapturerInfoChangeCallback> &callback)
361 {
362 if (audioCapturer_ == nullptr) {
363 return Status::ERROR_WRONG_STATE;
364 }
365 audioCapturerInfoChangeCallback_ = callback;
366 int32_t ret = audioCapturer_->SetAudioCapturerInfoChangeCallback(audioCapturerInfoChangeCallback_);
367 if (ret != (int32_t)Status::OK) {
368 MEDIA_LOG_E("SetAudioCapturerInfoChangeCallback fail error code: %{public}d", ret);
369 SetFaultEvent("SetAudioCapturerInfoChangeCallback error", ret);
370 return Status::ERROR_UNKNOWN;
371 }
372 return Status::OK;
373 }
374
GetCurrentCapturerChangeInfo(AudioStandard::AudioCapturerChangeInfo & changeInfo)375 Status AudioCaptureModule::GetCurrentCapturerChangeInfo(AudioStandard::AudioCapturerChangeInfo &changeInfo)
376 {
377 FALSE_RETURN_V_MSG_E(audioCapturer_ != nullptr, Status::ERROR_INVALID_OPERATION,
378 "audioCapturer is nullptr, cannot get audio capturer change info");
379 audioCapturer_->GetCurrentCapturerChangeInfo(changeInfo);
380 return Status::OK;
381 }
382
GetMaxAmplitude()383 int32_t AudioCaptureModule::GetMaxAmplitude()
384 {
385 if (!isTrackMaxAmplitude) {
386 isTrackMaxAmplitude = true;
387 }
388 int16_t value = maxAmplitude_;
389 maxAmplitude_ = 0;
390 return value;
391 }
392
SetAudioSource(AudioStandard::SourceType source)393 void AudioCaptureModule::SetAudioSource(AudioStandard::SourceType source)
394 {
395 options_.capturerInfo.sourceType = source;
396 }
397
TrackMaxAmplitude(int16_t * data,int32_t size)398 void AudioCaptureModule::TrackMaxAmplitude(int16_t *data, int32_t size)
399 {
400 for (int32_t i = 0; i < size; i++) {
401 int16_t value = *data++;
402 if (value < 0) {
403 value = -value;
404 }
405 if (maxAmplitude_ < value) {
406 maxAmplitude_ = value;
407 }
408 }
409 }
410
SetFaultEvent(const std::string & errMsg,int32_t ret)411 void AudioCaptureModule::SetFaultEvent(const std::string &errMsg, int32_t ret)
412 {
413 SetFaultEvent(errMsg + ", ret = " + std::to_string(ret));
414 }
415
SetFaultEvent(const std::string & errMsg)416 void AudioCaptureModule::SetFaultEvent(const std::string &errMsg)
417 {
418 AudioSourceFaultInfo audioSourceFaultInfo;
419 audioSourceFaultInfo.appName = bundleName_;
420 audioSourceFaultInfo.instanceId = std::to_string(instanceId_);
421 audioSourceFaultInfo.audioSourceType = options_.capturerInfo.sourceType;
422 audioSourceFaultInfo.errMsg = errMsg;
423 FaultRecordAudioEventWrite(audioSourceFaultInfo);
424 }
425
SetCallingInfo(int32_t appUid,int32_t appPid,const std::string & bundleName,uint64_t instanceId)426 void AudioCaptureModule::SetCallingInfo(int32_t appUid, int32_t appPid,
427 const std::string &bundleName, uint64_t instanceId)
428 {
429 appUid_ = appUid;
430 appPid_ = appPid;
431 bundleName_ = bundleName;
432 instanceId_ = instanceId;
433 }
434 } // namespace AudioCaptureModule
435 } // namespace Media
436 } // namespace OHOS
437