1 /*
2 * Copyright (C) 2021 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_capture_as_impl.h"
17 #include <vector>
18 #include <cmath>
19 #include "media_log.h"
20 #include "audio_errors.h"
21 #include "media_errors.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioCaptureAsImpl"};
25 constexpr size_t MAXIMUM_BUFFER_SIZE = 100000;
26 constexpr uint64_t SEC_TO_NANOSECOND = 1000000000;
27 }
28
29 namespace OHOS {
30 namespace Media {
AudioCaptureAsImpl()31 AudioCaptureAsImpl::AudioCaptureAsImpl()
32 {
33 }
34
~AudioCaptureAsImpl()35 AudioCaptureAsImpl::~AudioCaptureAsImpl()
36 {
37 if (audioCapturer_ != nullptr) {
38 (void)audioCapturer_->Release();
39 audioCapturer_ = nullptr;
40 }
41 }
42
SetCaptureParameter(uint32_t bitrate,uint32_t channels,uint32_t sampleRate)43 int32_t AudioCaptureAsImpl::SetCaptureParameter(uint32_t bitrate, uint32_t channels, uint32_t sampleRate)
44 {
45 (void)bitrate;
46 MEDIA_LOGD("SetCaptureParameter in, channels:%{public}u, sampleRate:%{public}u", channels, sampleRate);
47 if (audioCapturer_ == nullptr) {
48 audioCapturer_ = AudioStandard::AudioCapturer::Create(AudioStandard::AudioStreamType::STREAM_MUSIC);
49 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_NO_MEMORY);
50 }
51
52 AudioStandard::AudioCapturerParams params;
53 auto supportedSampleList = AudioStandard::AudioCapturer::GetSupportedSamplingRates();
54 CHECK_AND_RETURN_RET(supportedSampleList.size() > 0, MSERR_UNKNOWN);
55 bool isValidSampleRate = false;
56 for (auto iter = supportedSampleList.cbegin(); iter != supportedSampleList.cend(); ++iter) {
57 CHECK_AND_RETURN_RET(static_cast<int32_t>(*iter) > 0, MSERR_UNKNOWN);
58 uint32_t supportedSampleRate = static_cast<uint32_t>(*iter);
59 if (sampleRate <= supportedSampleRate) {
60 params.samplingRate = *iter;
61 isValidSampleRate = true;
62 break;
63 }
64 }
65 CHECK_AND_RETURN_RET(isValidSampleRate, MSERR_UNSUPPORT_AUD_SAMPLE_RATE);
66
67 auto supportedChannelsList = AudioStandard::AudioCapturer::GetSupportedChannels();
68 CHECK_AND_RETURN_RET(supportedChannelsList.size() > 0, MSERR_UNKNOWN);
69 bool isValidChannels = false;
70 for (auto iter = supportedChannelsList.cbegin(); iter != supportedChannelsList.cend(); ++iter) {
71 CHECK_AND_RETURN_RET(static_cast<int32_t>(*iter) > 0, MSERR_UNKNOWN);
72 uint32_t supportedChannels = static_cast<uint32_t>(*iter);
73 if (channels == supportedChannels) {
74 params.audioChannel = *iter;
75 isValidChannels = true;
76 break;
77 }
78 }
79 CHECK_AND_RETURN_RET(isValidChannels, MSERR_UNSUPPORT_AUD_CHANNEL_NUM);
80
81 params.audioSampleFormat = AudioStandard::SAMPLE_S16LE;
82 params.audioEncoding = AudioStandard::ENCODING_PCM;
83 MEDIA_LOGD("SetCaptureParameter out, channels:%{public}d, sampleRate:%{public}d",
84 params.audioChannel, params.samplingRate);
85 CHECK_AND_RETURN_RET(audioCapturer_->SetParams(params) == AudioStandard::SUCCESS, MSERR_UNKNOWN);
86 CHECK_AND_RETURN_RET(audioCapturer_->GetBufferSize(bufferSize_) == AudioStandard::SUCCESS, MSERR_UNKNOWN);
87 MEDIA_LOGD("audio buffer size is: %{public}zu", bufferSize_);
88 CHECK_AND_RETURN_RET_LOG(bufferSize_ < MAXIMUM_BUFFER_SIZE, MSERR_UNKNOWN, "audio buffer size too long");
89 return MSERR_OK;
90 }
91
GetCaptureParameter(uint32_t & bitrate,uint32_t & channels,uint32_t & sampleRate)92 int32_t AudioCaptureAsImpl::GetCaptureParameter(uint32_t &bitrate, uint32_t &channels, uint32_t &sampleRate)
93 {
94 (void)bitrate;
95 MEDIA_LOGD("GetCaptureParameter");
96 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
97 AudioStandard::AudioCapturerParams params;
98 CHECK_AND_RETURN_RET(audioCapturer_->GetParams(params) == AudioStandard::SUCCESS, MSERR_UNKNOWN);
99 channels = params.audioChannel;
100 sampleRate = params.samplingRate;
101 MEDIA_LOGD("get channels:%{public}u, sampleRate:%{public}u from audio server", channels, sampleRate);
102 CHECK_AND_RETURN_RET(bufferSize_ > 0 && channels > 0 && sampleRate > 0, MSERR_UNKNOWN);
103 constexpr uint32_t bitsPerByte = 8;
104 bufferDurationNs_ = (bufferSize_ * SEC_TO_NANOSECOND) /
105 (sampleRate * (AudioStandard::SAMPLE_S16LE / bitsPerByte) * channels);
106
107 MEDIA_LOGD("audio frame duration is (%{public}" PRIu64 ") ns", bufferDurationNs_);
108 return MSERR_OK;
109 }
110
GetSegmentInfo(uint64_t & start)111 int32_t AudioCaptureAsImpl::GetSegmentInfo(uint64_t &start)
112 {
113 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
114 AudioStandard::Timestamp timeStamp;
115 auto timestampBase = AudioStandard::Timestamp::Timestampbase::MONOTONIC;
116 CHECK_AND_RETURN_RET(audioCapturer_->GetAudioTime(timeStamp, timestampBase), MSERR_UNKNOWN);
117 CHECK_AND_RETURN_RET(timeStamp.time.tv_nsec >= 0 && timeStamp.time.tv_sec >= 0, MSERR_UNKNOWN);
118 if (((UINT64_MAX - timeStamp.time.tv_nsec) / SEC_TO_NANOSECOND) <= static_cast<uint64_t>(timeStamp.time.tv_sec)) {
119 MEDIA_LOGW("audio frame pts too long, this shouldn't happen");
120 }
121 start = timeStamp.time.tv_nsec + timeStamp.time.tv_sec * SEC_TO_NANOSECOND;
122 MEDIA_LOGI("timestamp from audioCapturer: %{public}" PRIu64 "", start);
123 return MSERR_OK;
124 }
125
GetBuffer()126 std::shared_ptr<AudioBuffer> AudioCaptureAsImpl::GetBuffer()
127 {
128 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, nullptr);
129 std::shared_ptr<AudioBuffer> buffer = std::make_shared<AudioBuffer>();
130 CHECK_AND_RETURN_RET(bufferSize_ > 0 && bufferSize_ < MAXIMUM_BUFFER_SIZE, nullptr);
131 buffer->gstBuffer = gst_buffer_new_allocate(nullptr, bufferSize_, nullptr);
132 CHECK_AND_RETURN_RET(buffer->gstBuffer != nullptr, nullptr);
133
134 GstMapInfo map = GST_MAP_INFO_INIT;
135 if (gst_buffer_map(buffer->gstBuffer, &map, GST_MAP_READ) != TRUE) {
136 gst_buffer_unref(buffer->gstBuffer);
137 return nullptr;
138 }
139 bool isBlocking = true;
140 int32_t bytesRead = audioCapturer_->Read(*(map.data), map.size, isBlocking);
141 gst_buffer_unmap(buffer->gstBuffer, &map);
142 if (bytesRead <= 0) {
143 gst_buffer_unref(buffer->gstBuffer);
144 return nullptr;
145 }
146
147 if (GetSegmentInfo(timestamp_) != MSERR_OK) {
148 gst_buffer_unref(buffer->gstBuffer);
149 return nullptr;
150 }
151
152 {
153 std::lock_guard<std::mutex> lock(pauseMutex_);
154 if (isPause_) {
155 pausedTime_ = timestamp_;
156 isPause_ = false;
157 MEDIA_LOGD("audio pause timestamp %{public}" PRIu64 "", pausedTime_);
158 }
159
160 if (isResume_) {
161 resumeTime_ = timestamp_;
162 MEDIA_LOGD("audio resume timestamp %{public}" PRIu64 "", resumeTime_);
163 persistTime_ = std::fabs(resumeTime_ - pausedTime_);
164 totalPauseTime_ += persistTime_;
165 isResume_ = false;
166 MEDIA_LOGD("audio has %{public}d times pause, total PauseTime: %{public}" PRIu64 "",
167 pausedCount_ ,totalPauseTime_);
168 }
169 }
170
171 buffer->timestamp = timestamp_ - totalPauseTime_;
172 buffer->duration = bufferDurationNs_;
173 buffer->dataLen = bufferSize_;
174 return buffer;
175 }
176
StartAudioCapture()177 int32_t AudioCaptureAsImpl::StartAudioCapture()
178 {
179 MEDIA_LOGD("StartAudioCapture");
180 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
181 CHECK_AND_RETURN_RET(audioCapturer_->Start(), MSERR_UNKNOWN);
182 return MSERR_OK;
183 }
184
StopAudioCapture()185 int32_t AudioCaptureAsImpl::StopAudioCapture()
186 {
187 MEDIA_LOGD("StopAudioCapture");
188 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
189 if (audioCapturer_->GetStatus() == AudioStandard::CapturerState::CAPTURER_RUNNING) {
190 CHECK_AND_RETURN_RET(audioCapturer_->Stop(), MSERR_UNKNOWN);
191 }
192 if (audioCapturer_->GetStatus() != AudioStandard::CapturerState::CAPTURER_RELEASED) {
193 CHECK_AND_RETURN_RET(audioCapturer_->Release(), MSERR_UNKNOWN);
194 }
195 audioCapturer_ = nullptr;
196 pausedTime_ = 0;
197 resumeTime_ = 0;
198 persistTime_ = 0;
199 totalPauseTime_ = 0;
200 pausedCount_ = 0;
201 return MSERR_OK;
202 }
203
PauseAudioCapture()204 int32_t AudioCaptureAsImpl::PauseAudioCapture()
205 {
206 MEDIA_LOGD("PauseAudioCapture");
207 {
208 std::lock_guard<std::mutex> lock(pauseMutex_);
209 isPause_ = true;
210 pausedCount_++; // add one pause time count
211 }
212
213 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
214 if (audioCapturer_->GetStatus() == AudioStandard::CapturerState::CAPTURER_RUNNING) {
215 CHECK_AND_RETURN_RET(audioCapturer_->Stop(), MSERR_UNKNOWN);
216 }
217 MEDIA_LOGD("exit PauseAudioCapture");
218 return MSERR_OK;
219 }
220
ResumeAudioCapture()221 int32_t AudioCaptureAsImpl::ResumeAudioCapture()
222 {
223 MEDIA_LOGD("ResumeAudioCapture");
224 {
225 std::lock_guard<std::mutex> lock(pauseMutex_);
226 isResume_ = true;
227 }
228
229 CHECK_AND_RETURN_RET(audioCapturer_ != nullptr, MSERR_INVALID_OPERATION);
230 CHECK_AND_RETURN_RET(audioCapturer_->Start(), MSERR_UNKNOWN);
231
232 return MSERR_OK;
233 }
234 } // namespace Media
235 } // namespace OHOS
236