• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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