1 /*
2 * Copyright (c) 2022-2023 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_decode_transport.h"
17
18 #include "audio_data_channel.h"
19 #include "audio_decoder_processor.h"
20 #include "audio_direct_processor.h"
21 #include "audio_param.h"
22 #include "daudio_errorcode.h"
23 #include "daudio_log.h"
24
25 #undef DH_LOG_TAG
26 #define DH_LOG_TAG "AudioDecodeTransport"
27
28 namespace OHOS {
29 namespace DistributedHardware {
SetUp(const AudioParam & localParam,const AudioParam & remoteParam,const std::shared_ptr<IAudioDataTransCallback> & callback,const PortCapType capType)30 int32_t AudioDecodeTransport::SetUp(const AudioParam &localParam, const AudioParam &remoteParam,
31 const std::shared_ptr<IAudioDataTransCallback> &callback, const PortCapType capType)
32 {
33 if (callback == nullptr) {
34 DHLOGE("The parameter is empty.");
35 return ERR_DH_AUDIO_TRANS_ERROR;
36 }
37 dataTransCallback_ = callback;
38 context_ = std::make_shared<AudioTransportContext>();
39 context_->SetTransportStatus(TRANSPORT_STATE_STOP);
40 int32_t ret = InitAudioDecodeTransport(localParam, remoteParam, capType);
41 if (ret != DH_SUCCESS) {
42 DHLOGE("Init audio encode transport, ret: %d.", ret);
43 return ret;
44 }
45 capType_ = capType;
46 DHLOGI("SetUp success.");
47 return DH_SUCCESS;
48 }
49
Start()50 int32_t AudioDecodeTransport::Start()
51 {
52 DHLOGI("Start audio decode transport.");
53 if (audioChannel_ == nullptr || context_ == nullptr) {
54 DHLOGE("Audio channel or context is null.");
55 return ERR_DH_AUDIO_NULLPTR;
56 }
57 if (capType_ == CAP_MIC && audioChannel_->OpenSession() != DH_SUCCESS) {
58 DHLOGE("Audio channel open session failed.");
59 return ERR_DH_AUDIO_TRANS_SESSION_NOT_OPEN;
60 }
61 int32_t ret = context_->Start();
62 if (ret != DH_SUCCESS) {
63 DHLOGE("Context start failed ret: %d.", ret);
64 audioChannel_->CloseSession();
65 return ret;
66 }
67 return DH_SUCCESS;
68 }
69
Stop()70 int32_t AudioDecodeTransport::Stop()
71 {
72 DHLOGI("Stop audio decode transport.");
73 if (audioChannel_ != nullptr) {
74 audioChannel_->CloseSession();
75 }
76 if (context_ == nullptr) {
77 DHLOGE("Context is null.");
78 return ERR_DH_AUDIO_NULLPTR;
79 }
80 return context_->Stop();
81 }
82
Pause()83 int32_t AudioDecodeTransport::Pause()
84 {
85 DHLOGI("Pause.");
86 if (context_ == nullptr) {
87 DHLOGE("Context is null.");
88 return ERR_DH_AUDIO_NULLPTR;
89 }
90 return context_->Pause();
91 }
92
Restart(const AudioParam & localParam,const AudioParam & remoteParam)93 int32_t AudioDecodeTransport::Restart(const AudioParam &localParam, const AudioParam &remoteParam)
94 {
95 DHLOGI("Restart.");
96 int32_t ret = RegisterProcessorListener(localParam, remoteParam);
97 if (ret != DH_SUCCESS) {
98 DHLOGE("Register processor listener failed, ret: %d.", ret);
99 processor_ = nullptr;
100 return ERR_DH_AUDIO_TRANS_ERROR;
101 }
102 if (context_ == nullptr) {
103 DHLOGE("Context is null.");
104 return ERR_DH_AUDIO_NULLPTR;
105 }
106 return context_->Restart(localParam, remoteParam);
107 }
108
Release()109 int32_t AudioDecodeTransport::Release()
110 {
111 DHLOGI("Release audio decode transport.");
112 bool releaseStatus = true;
113 if (processor_ != nullptr) {
114 int32_t ret = processor_->ReleaseAudioProcessor();
115 if (ret != DH_SUCCESS) {
116 DHLOGE("Release audio processor failed, ret: %d.", ret);
117 releaseStatus = false;
118 }
119 }
120 if (audioChannel_ != nullptr) {
121 int32_t ret = audioChannel_->ReleaseSession();
122 if (ret != DH_SUCCESS) {
123 DHLOGE("Release session failed, ret: %d.", ret);
124 releaseStatus = false;
125 }
126 }
127 if (!releaseStatus) {
128 DHLOGE("The releaseStatus is false.");
129 return ERR_DH_AUDIO_TRANS_ERROR;
130 }
131 DHLOGI("Release success.");
132 return DH_SUCCESS;
133 }
134
FeedAudioData(std::shared_ptr<AudioData> & audioData)135 int32_t AudioDecodeTransport::FeedAudioData(std::shared_ptr<AudioData> &audioData)
136 {
137 (void)audioData;
138 return DH_SUCCESS;
139 }
140
CreateCtrl()141 int32_t AudioDecodeTransport::CreateCtrl()
142 {
143 DHLOGI("create ctrl not support.");
144 return DH_SUCCESS;
145 }
146
InitEngine(IAVEngineProvider * providerPtr)147 int32_t AudioDecodeTransport::InitEngine(IAVEngineProvider *providerPtr)
148 {
149 (void)providerPtr;
150 return DH_SUCCESS;
151 }
152
SendMessage(uint32_t type,std::string content,std::string dstDevId)153 int32_t AudioDecodeTransport::SendMessage(uint32_t type, std::string content, std::string dstDevId)
154 {
155 (void)type;
156 (void)content;
157 (void)dstDevId;
158 DHLOGI("Send message not support.");
159 return DH_SUCCESS;
160 }
161
OnSessionOpened()162 void AudioDecodeTransport::OnSessionOpened()
163 {
164 DHLOGI("On channel session opened.");
165 auto cbObj = dataTransCallback_.lock();
166 if (cbObj == nullptr) {
167 DHLOGE("On channel session opened. Callback is nullptr.");
168 return;
169 }
170 cbObj->OnStateChange(AudioEventType::DATA_OPENED);
171 }
172
OnSessionClosed()173 void AudioDecodeTransport::OnSessionClosed()
174 {
175 DHLOGI("On channel session closed.");
176 auto cbObj = dataTransCallback_.lock();
177 if (cbObj == nullptr) {
178 DHLOGE("On channel session closed. Callback is nullptr.");
179 return;
180 }
181 cbObj->OnStateChange(AudioEventType::DATA_CLOSED);
182 }
183
OnDataReceived(const std::shared_ptr<AudioData> & data)184 void AudioDecodeTransport::OnDataReceived(const std::shared_ptr<AudioData> &data)
185 {
186 DHLOGI("On audio data received.");
187 if (processor_ == nullptr) {
188 DHLOGE("Processor is null, setup first.");
189 return;
190 }
191
192 int32_t ret = processor_->FeedAudioProcessor(data);
193 if (ret != DH_SUCCESS) {
194 DHLOGE("Feed audio processor failed ret: %d.", ret);
195 }
196 }
197
OnEventReceived(const AudioEvent & event)198 void AudioDecodeTransport::OnEventReceived(const AudioEvent &event)
199 {
200 (void)event;
201 }
202
OnAudioDataDone(const std::shared_ptr<AudioData> & outputData)203 void AudioDecodeTransport::OnAudioDataDone(const std::shared_ptr<AudioData> &outputData)
204 {
205 DHLOGI("On audio data done.");
206 std::lock_guard<std::mutex> lock(dataQueueMtx_);
207 auto cbObj = dataTransCallback_.lock();
208 if (cbObj == nullptr) {
209 DHLOGE("On audio data done. Callback is nullptr.");
210 return;
211 }
212 cbObj->OnDecodeTransDataDone(outputData);
213 }
214
OnStateNotify(const AudioEvent & event)215 void AudioDecodeTransport::OnStateNotify(const AudioEvent &event)
216 {
217 (void)event;
218 }
219
InitAudioDecodeTransport(const AudioParam & localParam,const AudioParam & remoteParam,const PortCapType capType)220 int32_t AudioDecodeTransport::InitAudioDecodeTransport(const AudioParam &localParam,
221 const AudioParam &remoteParam, const PortCapType capType)
222 {
223 int32_t ret = RegisterChannelListener(capType);
224 if (ret != DH_SUCCESS) {
225 DHLOGE("Register channel listener failed, ret: %d.", ret);
226 audioChannel_ = nullptr;
227 return ERR_DH_AUDIO_TRANS_ERROR;
228 }
229
230 ret = RegisterProcessorListener(localParam, remoteParam);
231 if (ret != DH_SUCCESS) {
232 DHLOGE("Register processor listener failed, ret: %d.", ret);
233 processor_ = nullptr;
234 return ERR_DH_AUDIO_TRANS_ERROR;
235 }
236 audioParam_ = remoteParam;
237 return DH_SUCCESS;
238 }
239
RegisterChannelListener(const PortCapType capType)240 int32_t AudioDecodeTransport::RegisterChannelListener(const PortCapType capType)
241 {
242 DHLOGI("Register Channel Listener.");
243 audioChannel_ = std::make_shared<AudioDataChannel>(peerDevId_);
244 int32_t result = (capType == CAP_SPK) ?
245 audioChannel_->CreateSession(shared_from_this(), DATA_SPEAKER_SESSION_NAME) :
246 audioChannel_->CreateSession(shared_from_this(), DATA_MIC_SESSION_NAME);
247 if (result != DH_SUCCESS) {
248 DHLOGE("Create session failed.");
249 return ERR_DH_AUDIO_TRANS_ERROR;
250 }
251 if (context_ == nullptr) {
252 DHLOGE("Register channel listener error, state context is null");
253 return ERR_DH_AUDIO_NULLPTR;
254 }
255 context_->SetAudioChannel(audioChannel_);
256 return DH_SUCCESS;
257 }
258
RegisterProcessorListener(const AudioParam & localParam,const AudioParam & remoteParam)259 int32_t AudioDecodeTransport::RegisterProcessorListener(const AudioParam &localParam, const AudioParam &remoteParam)
260 {
261 DHLOGI("Register processor listener.");
262 if (localParam.renderOpts.renderFlags == MMAP_MODE || localParam.captureOpts.capturerFlags == MMAP_MODE) {
263 DHLOGI("Use direct processor, renderFlags: %d, capturerFlags: %d.",
264 localParam.renderOpts.renderFlags, localParam.captureOpts.capturerFlags);
265 processor_ = std::make_shared<AudioDirectProcessor>();
266 } else {
267 processor_ = std::make_shared<AudioDecoderProcessor>();
268 }
269 int32_t ret = processor_->ConfigureAudioProcessor(localParam.comParam, remoteParam.comParam, shared_from_this());
270 if (ret != DH_SUCCESS) {
271 DHLOGE("Configure audio processor failed.");
272 return ret;
273 }
274 if (context_ == nullptr) {
275 DHLOGE("Register processor listener error, state context is null");
276 return ERR_DH_AUDIO_NULLPTR;
277 }
278 context_->SetAudioProcessor(processor_);
279 return DH_SUCCESS;
280 }
281 } // namespace DistributedHardware
282 } // namespace OHOS
283