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 "camera_log.h"
19 #include "camera_util.h"
20 #include "sample_info.h"
21 #include <cstring>
22 
23 namespace OHOS {
24 namespace CameraStandard {
25 
AudioDeferredProcess()26 AudioDeferredProcess::AudioDeferredProcess()
27 {
28     MEDIA_INFO_LOG("AudioDeferredProcess() Enter");
29     if (!offlineAudioEffectManager_) {
30         offlineAudioEffectManager_ = std::make_unique<OfflineAudioEffectManager>();
31     }
32 }
33 
~AudioDeferredProcess()34 AudioDeferredProcess::~AudioDeferredProcess()
35 {
36     MEDIA_INFO_LOG("~AudioDeferredProcess Enter");
37     Release();
38 }
39 
GetOfflineEffectChain()40 int32_t AudioDeferredProcess::GetOfflineEffectChain()
41 {
42     MEDIA_INFO_LOG("AudioDeferredProcess::GetOfflineEffectChain Enter");
43     if (!offlineAudioEffectManager_) {
44         MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain offlineAudioEffectManager_ is nullptr");
45         return -1;
46     }
47     vector<std::string> effectChains = offlineAudioEffectManager_->GetOfflineAudioEffectChains();
48     if (std::find(effectChains.begin(), effectChains.end(), chainName_) == effectChains.end()) {
49         MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain no effectChain moving photo needed");
50         return -1;
51     }
52     offlineEffectChain_ = offlineAudioEffectManager_->CreateOfflineAudioEffectChain(chainName_);
53     if (!offlineEffectChain_) {
54         MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain ERR");
55         return -1;
56     }
57     return CAMERA_OK;
58 }
59 
ConfigOfflineAudioEffectChain(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)60 int32_t AudioDeferredProcess::ConfigOfflineAudioEffectChain(const AudioStreamInfo& inputOptions,
61     const AudioStreamInfo& outputOptions)
62 {
63     MEDIA_INFO_LOG("AudioDeferredProcess::ConfigOfflineAudioEffectChain Enter");
64     if (offlineEffectChain_->Configure(inputOptions, outputOptions) != 0) {
65         MEDIA_ERR_LOG("AudioDeferredProcess::ConfigOfflineAudioEffectChain Err");
66         return -1;
67     }
68     inputOptions_ = inputOptions;
69     outputOptions_ = outputOptions;
70     return CAMERA_OK;
71 }
72 
PrepareOfflineAudioEffectChain()73 int32_t AudioDeferredProcess::PrepareOfflineAudioEffectChain()
74 {
75     MEDIA_INFO_LOG("AudioDeferredProcess::PrepareOfflineAudioEffectChain Enter");
76     if (offlineEffectChain_->Prepare() != 0) {
77         MEDIA_ERR_LOG("AudioDeferredProcess::PrepareOfflineAudioEffectChain Err");
78         return -1;
79     }
80     return CAMERA_OK;
81 }
82 
GetMaxBufferSize(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)83 int32_t AudioDeferredProcess::GetMaxBufferSize(const AudioStreamInfo& inputOptions,
84     const AudioStreamInfo& outputOptions)
85 {
86     MEDIA_INFO_LOG("AudioDeferredProcess::GetMaxBufferSize Enter");
87     if (offlineEffectChain_->GetEffectBufferSize(maxUnprocessedBufferSize_, maxProcessedBufferSize_) != 0) {
88         MEDIA_ERR_LOG("AudioDeferredProcess::GetMaxBufferSize Err");
89         return -1;
90     }
91     oneUnprocessedSize_ = inputOptions.samplingRate / ONE_THOUSAND *
92         inputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
93     oneProcessedSize_ = outputOptions.samplingRate / ONE_THOUSAND *
94         outputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
95     MEDIA_INFO_LOG("AudioDeferredProcess::GetMaxBufferSize %{public}d", oneProcessedSize_);
96     if (oneUnprocessedSize_ * PROCESS_BATCH_SIZE > maxUnprocessedBufferSize_ ||
97         oneProcessedSize_ * PROCESS_BATCH_SIZE > maxProcessedBufferSize_) {
98         MEDIA_ERR_LOG("AudioDeferredProcess::GetMaxBufferSize MaxBufferSize Not Enough");
99         return -1;
100     }
101     return CAMERA_OK;
102 }
103 
GetOneUnprocessedSize()104 uint32_t AudioDeferredProcess::GetOneUnprocessedSize()
105 {
106     return oneUnprocessedSize_;
107 }
108 
GetOutputSampleRate()109 AudioSamplingRate AudioDeferredProcess::GetOutputSampleRate()
110 {
111     return outputOptions_.samplingRate;
112 }
113 
GetOutputChannelCount()114 AudioChannel AudioDeferredProcess::GetOutputChannelCount()
115 {
116     return outputOptions_.channels;
117 }
118 
Process(vector<sptr<AudioRecord>> & audioRecords,vector<sptr<AudioRecord>> & processedRecords)119 int32_t AudioDeferredProcess::Process(vector<sptr<AudioRecord>>& audioRecords,
120     vector<sptr<AudioRecord>>& processedRecords)
121 {
122     if (offlineEffectChain_ == nullptr) {
123         MEDIA_WARNING_LOG("AudioDeferredProcess::Process offlineEffectChain_ is nullptr.");
124         return -1;
125     }
126     MEDIA_INFO_LOG("AudioDeferredProcess::Process Enter");
127     uint32_t audioRecordsLen = audioRecords.size();
128     std::unique_ptr<uint8_t[]> rawArr = std::make_unique<uint8_t[]>(oneUnprocessedSize_ * PROCESS_BATCH_SIZE);
129     std::unique_ptr<uint8_t[]> processedArr = std::make_unique<uint8_t[]>(oneProcessedSize_ * PROCESS_BATCH_SIZE);
130 
131     uint32_t count = 0;
132     std::lock_guard<std::mutex> lock(mutex_);
133     auto returnToRecords = [this, &processedRecords, &rawArr, &processedArr](uint32_t i, uint32_t batchSize)->void {
134         int32_t ret = offlineEffectChain_->Process(rawArr.get(), oneUnprocessedSize_ * PROCESS_BATCH_SIZE,
135             processedArr.get(), oneProcessedSize_ * PROCESS_BATCH_SIZE);
136         CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process err");
137         for (uint32_t j = 0; j < batchSize; ++ j) {
138             uint8_t* temp = new uint8_t[oneProcessedSize_];
139             ret = memcpy_s(temp, oneProcessedSize_, processedArr.get() + j * oneProcessedSize_, oneProcessedSize_);
140             CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process returnToRecords memcpy_s err");
141             processedRecords[i - batchSize + 1 + j]->SetAudioBuffer(temp);
142         }
143     };
144 
145     for (uint32_t i = 0; i < audioRecordsLen; i ++) {
146         int32_t ret = memcpy_s(rawArr.get() + count * oneUnprocessedSize_, oneUnprocessedSize_,
147             audioRecords[i]->GetAudioBuffer(), oneUnprocessedSize_);
148         CHECK_AND_PRINT_LOG(ret == 0, "AudioDeferredProcess::Process memcpy_s err");
149         if (count == PROCESS_BATCH_SIZE - 1) {
150             returnToRecords(i, PROCESS_BATCH_SIZE);
151         } else if (i == audioRecordsLen - 1) { // last
152             returnToRecords(i, count + 1);
153         }
154         count = (count + 1) % PROCESS_BATCH_SIZE;
155     }
156 
157     return CAMERA_OK;
158 }
159 
Release()160 void AudioDeferredProcess::Release()
161 {
162     std::lock_guard<std::mutex> lock(mutex_);
163     MEDIA_INFO_LOG("AudioDeferredProcess::Release Enter");
164     if (offlineEffectChain_) {
165         offlineEffectChain_->Release();
166     }
167     offlineEffectChain_ = nullptr;
168     offlineAudioEffectManager_ = nullptr;
169 }
170 
171 } // CameraStandard
172 } // OHOS
173