1 /*
2 * Copyright (c) 2022 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 #include "daudio_render_internal.h"
16
17 #include <securec.h>
18
19 #include "daudio_attribute_internal.h"
20 #include "daudio_control_internal.h"
21 #include "daudio_errorcode.h"
22 #include "daudio_log.h"
23 #include "daudio_scene_internal.h"
24 #include "daudio_volume_internal.h"
25
26 #undef DH_LOG_TAG
27 #define DH_LOG_TAG "DAudioRenderInternal"
28
29 namespace OHOS {
30 namespace DistributedHardware {
31 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
32
GetLatencyInternal(struct AudioRender * render,uint32_t * ms)33 static int32_t GetLatencyInternal(struct AudioRender *render, uint32_t *ms)
34 {
35 if (render == nullptr || ms == nullptr) {
36 DHLOGE("The parameter is empty.");
37 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
38 }
39
40 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
41 if (context->proxy_ == nullptr) {
42 DHLOGE("The context or proxy for the context is nullptr.");
43 return ERR_DH_AUDIO_HDI_NULLPTR;
44 }
45 return context->proxy_->GetLatency(*ms);
46 }
47
RenderFrameInternal(struct AudioRender * render,const void * frame,uint64_t requestBytes,uint64_t * replyBytes)48 static int32_t RenderFrameInternal(struct AudioRender *render, const void *frame, uint64_t requestBytes,
49 uint64_t *replyBytes)
50 {
51 DHLOGI("Render frame.");
52 if (render == nullptr || frame == nullptr || requestBytes == 0 || replyBytes == nullptr) {
53 DHLOGE("The parameter is empty.");
54 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
55 }
56
57 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
58 if (context->proxy_ == nullptr) {
59 DHLOGE("The context or proxy for the context is nullptr.");
60 return ERR_DH_AUDIO_HDI_NULLPTR;
61 }
62 const uint8_t *uframe = reinterpret_cast<const uint8_t *>(frame);
63 std::vector<int8_t> frameHal(requestBytes);
64 int32_t ret = memcpy_s(frameHal.data(), requestBytes, uframe, requestBytes);
65 if (ret != EOK) {
66 DHLOGE("Copy render frame failed, error code %d.", ret);
67 return ERR_DH_AUDIO_HDI_CALL_FAILED;
68 }
69 return context->proxy_->RenderFrame(frameHal, *replyBytes);
70 }
71
GetRenderPositionInternal(struct AudioRender * render,uint64_t * frames,struct::AudioTimeStamp * time)72 static int32_t GetRenderPositionInternal(struct AudioRender *render, uint64_t *frames,
73 struct ::AudioTimeStamp *time)
74 {
75 if (render == nullptr || frames == nullptr || time == nullptr) {
76 DHLOGE("The parameter is empty.");
77 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
78 }
79
80 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
81 if (context->proxy_ == nullptr) {
82 DHLOGE("The context or proxy for the context is nullptr.");
83 return ERR_DH_AUDIO_HDI_NULLPTR;
84 }
85 AudioTimeStamp timeHal;
86 int32_t ret = context->proxy_->GetRenderPosition(*frames, timeHal);
87 if (ret != DH_SUCCESS) {
88 return ret;
89 }
90 time->tvSec = static_cast<int64_t>(timeHal.tvSec);
91 time->tvNSec = static_cast<int64_t>(timeHal.tvNSec);
92 return DH_SUCCESS;
93 }
94
SetRenderSpeedInternal(struct AudioRender * render,float speed)95 static int32_t SetRenderSpeedInternal(struct AudioRender *render, float speed)
96 {
97 if (render == nullptr) {
98 DHLOGE("The parameter is empty.");
99 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
100 }
101
102 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
103 if (context->proxy_ == nullptr) {
104 DHLOGE("The context or proxy for the context is nullptr.");
105 return ERR_DH_AUDIO_HDI_NULLPTR;
106 }
107 return context->proxy_->SetRenderSpeed(speed);
108 }
109
GetRenderSpeedInternal(struct AudioRender * render,float * speed)110 static int32_t GetRenderSpeedInternal(struct AudioRender *render, float *speed)
111 {
112 if (render == nullptr || speed == nullptr) {
113 DHLOGE("The parameter is empty.");
114 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
115 }
116
117 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
118 if (context->proxy_ == nullptr) {
119 DHLOGE("The context or proxy for the context is nullptr.");
120 return ERR_DH_AUDIO_HDI_NULLPTR;
121 }
122 return context->proxy_->GetRenderSpeed(*speed);
123 }
124
SetChannelModeInternal(struct AudioRender * render,enum::AudioChannelMode mode)125 static int32_t SetChannelModeInternal(struct AudioRender *render, enum ::AudioChannelMode mode)
126 {
127 if (render == nullptr) {
128 DHLOGE("The parameter is empty.");
129 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
130 }
131
132 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
133 if (context->proxy_ == nullptr) {
134 DHLOGE("The context or proxy for the context is nullptr.");
135 return ERR_DH_AUDIO_HDI_NULLPTR;
136 }
137 return context->proxy_->SetChannelMode(static_cast<AudioChannelMode>(mode));
138 }
139
GetChannelModeInternal(struct AudioRender * render,enum::AudioChannelMode * mode)140 static int32_t GetChannelModeInternal(struct AudioRender *render, enum ::AudioChannelMode *mode)
141 {
142 if (render == nullptr || mode == nullptr) {
143 DHLOGE("The parameter is empty.");
144 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
145 }
146
147 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
148 if (context->proxy_ == nullptr) {
149 DHLOGE("The context or proxy for the context is nullptr.");
150 return ERR_DH_AUDIO_HDI_NULLPTR;
151 }
152 return context->proxy_->GetChannelMode(*(reinterpret_cast<AudioChannelMode *>(mode)));
153 }
154
RegCallbackInternal(struct AudioRender * render,::RenderCallback callback,void * cookie)155 static int32_t RegCallbackInternal(struct AudioRender *render, ::RenderCallback callback, void *cookie)
156 {
157 if (render == nullptr || callback == nullptr || cookie == nullptr) {
158 DHLOGE("The parameter is empty.");
159 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
160 }
161
162 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
163 if (context->proxy_ == nullptr) {
164 DHLOGE("The context or proxy for the context is nullptr.");
165 return ERR_DH_AUDIO_HDI_NULLPTR;
166 }
167 std::lock_guard<std::mutex> lock(context->mtx_);
168 if (context->callbackInternal_ == nullptr || callback != context->callback_) {
169 context->callbackInternal_ = std::make_unique<AudioRenderCallbackContext>(callback, cookie);
170 } else {
171 return DH_SUCCESS;
172 }
173
174 if (context->callbackInternal_->callbackStub_ == nullptr) {
175 context->callbackInternal_ = nullptr;
176 return ERR_DH_AUDIO_HDI_CALL_FAILED;
177 }
178 int32_t ret = context->proxy_->RegCallback(context->callbackInternal_->callbackStub_, 0);
179 if (ret == DH_SUCCESS) {
180 context->callback_ = callback;
181 } else {
182 context->callbackInternal_ = nullptr;
183 }
184 return ret;
185 }
186
DrainBufferInternal(struct AudioRender * render,enum::AudioDrainNotifyType * type)187 static int32_t DrainBufferInternal(struct AudioRender *render, enum ::AudioDrainNotifyType *type)
188 {
189 if (render == nullptr || type == nullptr) {
190 DHLOGE("The parameter is empty.");
191 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
192 }
193
194 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
195 if (context->proxy_ == nullptr) {
196 DHLOGE("The context or proxy for the context is nullptr.");
197 return ERR_DH_AUDIO_HDI_NULLPTR;
198 }
199 return context->proxy_->DrainBuffer(*(reinterpret_cast<AudioDrainNotifyType *>(type)));
200 }
201
AudioRenderContext()202 AudioRenderContext::AudioRenderContext()
203 {
204 instance_.GetLatency = GetLatencyInternal;
205 instance_.RenderFrame = RenderFrameInternal;
206 instance_.GetRenderPosition = GetRenderPositionInternal;
207 instance_.SetRenderSpeed = SetRenderSpeedInternal;
208 instance_.GetRenderSpeed = GetRenderSpeedInternal;
209 instance_.SetChannelMode = SetChannelModeInternal;
210 instance_.GetChannelMode = GetChannelModeInternal;
211 instance_.RegCallback = RegCallbackInternal;
212 instance_.DrainBuffer = DrainBufferInternal;
213 instance_.IsSupportsDrain = nullptr;
214
215 instance_.control.Start = AudioControlInternal<AudioRenderContext>::Start;
216 instance_.control.Stop = AudioControlInternal<AudioRenderContext>::Stop;
217 instance_.control.Pause = AudioControlInternal<AudioRenderContext>::Pause;
218 instance_.control.Resume = AudioControlInternal<AudioRenderContext>::Resume;
219 instance_.control.Flush = AudioControlInternal<AudioRenderContext>::Flush;
220 instance_.control.TurnStandbyMode = AudioControlInternal<AudioRenderContext>::TurnStandbyMode;
221 instance_.control.AudioDevDump = AudioControlInternal<AudioRenderContext>::AudioDevDump;
222
223 instance_.attr.GetFrameSize = AudioAttributeInternal<AudioRenderContext>::GetFrameSize;
224 instance_.attr.GetFrameCount = AudioAttributeInternal<AudioRenderContext>::GetFrameCount;
225 instance_.attr.SetSampleAttributes = AudioAttributeInternal<AudioRenderContext>::SetSampleAttributes;
226 instance_.attr.GetSampleAttributes = AudioAttributeInternal<AudioRenderContext>::GetSampleAttributes;
227 instance_.attr.GetCurrentChannelId = AudioAttributeInternal<AudioRenderContext>::GetCurrentChannelId;
228 instance_.attr.SetExtraParams = AudioAttributeInternal<AudioRenderContext>::SetExtraParams;
229 instance_.attr.GetExtraParams = AudioAttributeInternal<AudioRenderContext>::GetExtraParams;
230 instance_.attr.ReqMmapBuffer = AudioAttributeInternal<AudioRenderContext>::ReqMmapBuffer;
231 instance_.attr.GetMmapPosition = AudioAttributeInternal<AudioRenderContext>::GetMmapPosition;
232
233 instance_.scene.SelectScene = AudioSceneInternal<AudioRenderContext>::SelectScene;
234 instance_.scene.CheckSceneCapability = AudioSceneInternal<AudioRenderContext>::CheckSceneCapability;
235
236 instance_.volume.SetMute = AudioVolumeInternal<AudioRenderContext>::SetMute;
237 instance_.volume.GetMute = AudioVolumeInternal<AudioRenderContext>::GetMute;
238 instance_.volume.SetVolume = AudioVolumeInternal<AudioRenderContext>::SetVolume;
239 instance_.volume.GetVolume = AudioVolumeInternal<AudioRenderContext>::GetVolume;
240 instance_.volume.GetGainThreshold = AudioVolumeInternal<AudioRenderContext>::GetGainThreshold;
241 instance_.volume.SetGain = AudioVolumeInternal<AudioRenderContext>::SetGain;
242 instance_.volume.GetGain = AudioVolumeInternal<AudioRenderContext>::GetGain;
243
244 descHal_.portId = 0;
245 descHal_.pins = PIN_NONE;
246 }
247
~AudioRenderContext()248 AudioRenderContext::~AudioRenderContext() {}
249 } // namespace DistributedHardware
250 } // namespace OHOS