1 /*
2 * Copyright (c) 2024-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_deferred_process.h"
17
18 #include "utils/camera_log.h"
19 #include "camera_util.h"
20 #include <cstring>
21
22 namespace OHOS {
23 namespace CameraStandard {
24
AudioDeferredProcess()25 AudioDeferredProcess::AudioDeferredProcess()
26 {
27 MEDIA_INFO_LOG("AudioDeferredProcess() Enter");
28 }
29
~AudioDeferredProcess()30 AudioDeferredProcess::~AudioDeferredProcess()
31 {
32 MEDIA_INFO_LOG("~AudioDeferredProcess Enter");
33 Release();
34 }
35
GetOfflineEffectChain()36 int32_t AudioDeferredProcess::GetOfflineEffectChain()
37 {
38 CAMERA_SYNC_TRACE;
39 MEDIA_INFO_LOG("AudioDeferredProcess::GetOfflineEffectChain Enter");
40 if (!offlineAudioEffectManager_) {
41 offlineAudioEffectManager_ = std::make_unique<OfflineAudioEffectManager>();
42 }
43 vector<std::string> effectChains = offlineAudioEffectManager_->GetOfflineAudioEffectChains();
44 if (std::find(effectChains.begin(), effectChains.end(), chainName_) == effectChains.end()) {
45 MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain no effectChain moving photo needed");
46 return -1;
47 }
48 offlineEffectChain_ = offlineAudioEffectManager_->CreateOfflineAudioEffectChain(chainName_);
49 if (!offlineEffectChain_) {
50 MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain ERR");
51 return -1;
52 }
53 return CAMERA_OK;
54 }
55
StoreOptions(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)56 void AudioDeferredProcess::StoreOptions(const AudioStreamInfo& inputOptions,
57 const AudioStreamInfo& outputOptions)
58 {
59 CAMERA_SYNC_TRACE;
60 MEDIA_INFO_LOG("AudioDeferredProcess::StoreConfig Enter");
61 inputOptions_ = inputOptions;
62 outputOptions_ = outputOptions;
63 }
64
ConfigOfflineAudioEffectChain()65 int32_t AudioDeferredProcess::ConfigOfflineAudioEffectChain()
66 {
67 // LCOV_EXCL_START
68 CAMERA_SYNC_TRACE;
69 MEDIA_INFO_LOG("AudioDeferredProcess::ConfigOfflineAudioEffectChain Enter");
70 CHECK_RETURN_RET_ELOG(offlineEffectChain_->Configure(inputOptions_, outputOptions_) != 0, -1,
71 "AudioDeferredProcess::ConfigOfflineAudioEffectChain Err");
72 return CAMERA_OK;
73 // LCOV_EXCL_STOP
74 }
75
PrepareOfflineAudioEffectChain()76 int32_t AudioDeferredProcess::PrepareOfflineAudioEffectChain()
77 {
78 // LCOV_EXCL_START
79 CAMERA_SYNC_TRACE;
80 MEDIA_INFO_LOG("AudioDeferredProcess::PrepareOfflineAudioEffectChain Enter");
81 CHECK_RETURN_RET_ELOG(offlineEffectChain_->Prepare() != 0, -1,
82 "AudioDeferredProcess::PrepareOfflineAudioEffectChain Err");
83 return CAMERA_OK;
84 // LCOV_EXCL_STOP
85 }
86
GetMaxBufferSize(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)87 int32_t AudioDeferredProcess::GetMaxBufferSize(const AudioStreamInfo& inputOptions,
88 const AudioStreamInfo& outputOptions)
89 {
90 // LCOV_EXCL_START
91 CAMERA_SYNC_TRACE;
92 MEDIA_INFO_LOG("AudioDeferredProcess::GetMaxBufferSize Enter");
93 uint32_t maxUnprocessedBufferSize_ = 0;
94 uint32_t maxProcessedBufferSize_ = 0;
95 CHECK_RETURN_RET_ELOG(offlineEffectChain_->GetEffectBufferSize(maxUnprocessedBufferSize_,
96 maxProcessedBufferSize_) != 0, -1, "AudioDeferredProcess::GetMaxBufferSize Err");
97 oneUnprocessedSize_ = inputOptions.samplingRate / ONE_THOUSAND *
98 inputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
99 oneProcessedSize_ = outputOptions.samplingRate / ONE_THOUSAND *
100 outputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
101 CHECK_RETURN_RET_ELOG(oneUnprocessedSize_ * PROCESS_BATCH_SIZE > maxUnprocessedBufferSize_ ||
102 oneProcessedSize_ * PROCESS_BATCH_SIZE > maxProcessedBufferSize_, -1,
103 "AudioDeferredProcess::GetMaxBufferSize MaxBufferSize Not Enough");
104 return CAMERA_OK;
105 // LCOV_EXCL_STOP
106 }
107
GetOneUnprocessedSize()108 uint32_t AudioDeferredProcess::GetOneUnprocessedSize()
109 {
110 return oneUnprocessedSize_;
111 }
112
FadeOneBatch(std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr)113 void AudioDeferredProcess::FadeOneBatch(std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr)
114 {
115 // LCOV_EXCL_START
116 float rate;
117 int16_t* data = reinterpret_cast<int16_t*>(processedArr.data());
118 int32_t temp;
119 int32_t oneSize = outputOptions_.samplingRate / ONE_THOUSAND * DURATION_EACH_AUDIO_FRAME;
120 CHECK_RETURN_ELOG(oneSize >= MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
121 "AudioDeferredProcess::FadeOneBatch arrSize overSize");
122 for (int k = 0; k < oneSize; k++) {
123 temp = static_cast<int32_t>(data[k]);
124 rate = static_cast<float>(k) / oneSize;
125 temp = temp - static_cast<int32_t>(temp * rate);
126 data[k] = static_cast<int16_t>(temp);
127 }
128 // LCOV_EXCL_STOP
129 }
130
EffectChainProcess(std::array<uint8_t,MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE> & rawArr,std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr)131 void AudioDeferredProcess::EffectChainProcess(std::array<uint8_t, MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE>& rawArr,
132 std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr)
133 {
134 // LCOV_EXCL_START
135 int32_t ret = offlineEffectChain_->Process(rawArr.data(), oneUnprocessedSize_ * PROCESS_BATCH_SIZE,
136 processedArr.data(), oneProcessedSize_ * PROCESS_BATCH_SIZE);
137 CHECK_PRINT_ELOG(ret != 0, "AudioDeferredProcess::Process err");
138 // LCOV_EXCL_STOP
139 }
140
ReturnToRecords(std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr,vector<sptr<AudioRecord>> & processedRecords,uint32_t i,uint32_t batchSize)141 void AudioDeferredProcess::ReturnToRecords(std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr,
142 vector<sptr<AudioRecord>>& processedRecords, uint32_t i, uint32_t batchSize)
143 {
144 // LCOV_EXCL_START
145 for (uint32_t j = 0; j < batchSize; ++ j) {
146 uint8_t* temp = new uint8_t[oneProcessedSize_];
147 int32_t ret = memcpy_s(temp, oneProcessedSize_, processedArr.data() + j * oneProcessedSize_, oneProcessedSize_);
148 CHECK_PRINT_ELOG(ret != 0, "AudioDeferredProcess::Process returnToRecords memcpy_s err");
149 int64_t index = i + 1 + j - batchSize;
150 CHECK_RETURN_ELOG(index < 0 || index >= static_cast<int64_t>(processedRecords.size()),
151 "ReturnToRecords unexpected error occured");
152 processedRecords[index]->SetAudioBuffer(temp, oneProcessedSize_);
153 }
154 // LCOV_EXCL_STOP
155 }
156
MemsetAndCheck(void * dest,size_t destMax,int c,size_t count)157 void MemsetAndCheck(void *dest, size_t destMax, int c, size_t count)
158 {
159 // LCOV_EXCL_START
160 int32_t ret = memset_s(dest, destMax, c, count);
161 CHECK_PRINT_ELOG(ret != 0, "AudioDeferredProcess::Process memset_s err");
162 // LCOV_EXCL_STOP
163 }
164
Process(vector<sptr<AudioRecord>> & audioRecords,vector<sptr<AudioRecord>> & processedRecords)165 int32_t AudioDeferredProcess::Process(vector<sptr<AudioRecord>>& audioRecords,
166 vector<sptr<AudioRecord>>& processedRecords)
167 {
168 CAMERA_SYNC_TRACE;
169 if (offlineEffectChain_ == nullptr) {
170 MEDIA_WARNING_LOG("AudioDeferredProcess::Process offlineEffectChain_ is nullptr.");
171 return -1;
172 }
173 MEDIA_INFO_LOG("AudioDeferredProcess::Process Enter");
174 uint32_t audioRecordsLen = audioRecords.size();
175 CHECK_RETURN_RET_ELOG(0 == audioRecordsLen, CAMERA_OK, "audioRecords.size == 0");
176 // LCOV_EXCL_START
177 std::array<uint8_t, MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE> rawArr{};
178 std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> processedArr{};
179 uint32_t count = 0;
180 lock_guard<std::mutex> lock(mutex_);
181 for (uint32_t i = 0; i < audioRecordsLen; i ++) {
182 int32_t ret = memcpy_s(rawArr.data() + count * oneUnprocessedSize_, oneUnprocessedSize_,
183 audioRecords[i]->GetAudioBuffer(), oneUnprocessedSize_);
184 CHECK_PRINT_ELOG(ret != 0, "AudioDeferredProcess::Process memcpy_s err");
185 if (audioRecordsLen - 1 == i) {
186 MemsetAndCheck(rawArr.data(), MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE,
187 0, PROCESS_BATCH_SIZE * oneUnprocessedSize_);
188 EffectChainProcess(rawArr, processedArr);
189 MemsetAndCheck(processedArr.data(), MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
190 0, PROCESS_BATCH_SIZE * oneProcessedSize_);
191 ReturnToRecords(processedArr, processedRecords, i, count + 1);
192 } else if (audioRecordsLen >= PROCESS_BATCH_SIZE + 1 && i >= audioRecordsLen - PROCESS_BATCH_SIZE - 1 &&
193 count == PROCESS_BATCH_SIZE - 1) {
194 EffectChainProcess(rawArr, processedArr);
195 FadeOneBatch(processedArr);
196 MemsetAndCheck(processedArr.data() + oneProcessedSize_, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
197 0, (PROCESS_BATCH_SIZE - 1) * oneProcessedSize_);
198 ReturnToRecords(processedArr, processedRecords, i, PROCESS_BATCH_SIZE);
199 } else if (count == PROCESS_BATCH_SIZE - 1) {
200 EffectChainProcess(rawArr, processedArr);
201 ReturnToRecords(processedArr, processedRecords, i, PROCESS_BATCH_SIZE);
202 }
203 count = (count + 1) % PROCESS_BATCH_SIZE;
204 }
205 return CAMERA_OK;
206 // LCOV_EXCL_STOP
207 }
208
Release()209 void AudioDeferredProcess::Release()
210 {
211 CAMERA_SYNC_TRACE;
212 lock_guard<std::mutex> lock(mutex_);
213 MEDIA_INFO_LOG("AudioDeferredProcess::Release Enter");
214 CHECK_EXECUTE(offlineEffectChain_, offlineEffectChain_->Release());
215 offlineEffectChain_ = nullptr;
216 offlineAudioEffectManager_ = nullptr;
217 }
218
219 } // CameraStandard
220 } // OHOS