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