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 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
36 CHECK_NULL_RETURN(ms, ERR_DH_AUDIO_HDI_INVALID_PARAM);
37 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
38 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
39 return context->proxy_->GetLatency(*ms);
40 }
41
RenderFrameInternal(struct AudioRender * render,const void * frame,uint64_t requestBytes,uint64_t * replyBytes)42 static int32_t RenderFrameInternal(struct AudioRender *render, const void *frame, uint64_t requestBytes,
43 uint64_t *replyBytes)
44 {
45 DHLOGI("Render frame.");
46 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
47 CHECK_NULL_RETURN(frame, ERR_DH_AUDIO_HDI_INVALID_PARAM);
48 CHECK_NULL_RETURN(replyBytes, ERR_DH_AUDIO_HDI_INVALID_PARAM);
49 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
50 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
51
52 const uint8_t *uframe = reinterpret_cast<const uint8_t *>(frame);
53 std::vector<int8_t> frameHal(requestBytes);
54 int32_t ret = memcpy_s(frameHal.data(), requestBytes, uframe, requestBytes);
55 if (ret != EOK) {
56 DHLOGE("Copy render frame failed, error code %d.", ret);
57 return ERR_DH_AUDIO_HDI_CALL_FAILED;
58 }
59 return context->proxy_->RenderFrame(frameHal, *replyBytes);
60 }
61
GetRenderPositionInternal(struct AudioRender * render,uint64_t * frames,struct::AudioTimeStamp * time)62 static int32_t GetRenderPositionInternal(struct AudioRender *render, uint64_t *frames,
63 struct ::AudioTimeStamp *time)
64 {
65 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
66 CHECK_NULL_RETURN(frames, ERR_DH_AUDIO_HDI_INVALID_PARAM);
67 CHECK_NULL_RETURN(time, ERR_DH_AUDIO_HDI_INVALID_PARAM);
68
69 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
70 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
71 AudioTimeStamp timeHal;
72 int32_t ret = context->proxy_->GetRenderPosition(*frames, timeHal);
73 if (ret != DH_SUCCESS) {
74 return ret;
75 }
76 time->tvSec = static_cast<int64_t>(timeHal.tvSec);
77 time->tvNSec = static_cast<int64_t>(timeHal.tvNSec);
78 return DH_SUCCESS;
79 }
80
SetRenderSpeedInternal(struct AudioRender * render,float speed)81 static int32_t SetRenderSpeedInternal(struct AudioRender *render, float speed)
82 {
83 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
84 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
85 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
86 return context->proxy_->SetRenderSpeed(speed);
87 }
88
GetRenderSpeedInternal(struct AudioRender * render,float * speed)89 static int32_t GetRenderSpeedInternal(struct AudioRender *render, float *speed)
90 {
91 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
92 CHECK_NULL_RETURN(speed, ERR_DH_AUDIO_HDI_INVALID_PARAM);
93 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
94 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
95 return context->proxy_->GetRenderSpeed(*speed);
96 }
97
SetChannelModeInternal(struct AudioRender * render,enum::AudioChannelMode mode)98 static int32_t SetChannelModeInternal(struct AudioRender *render, enum ::AudioChannelMode mode)
99 {
100 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
101 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
102 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
103 return context->proxy_->SetChannelMode(static_cast<AudioChannelMode>(mode));
104 }
105
GetChannelModeInternal(struct AudioRender * render,enum::AudioChannelMode * mode)106 static int32_t GetChannelModeInternal(struct AudioRender *render, enum ::AudioChannelMode *mode)
107 {
108 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
109 CHECK_NULL_RETURN(mode, ERR_DH_AUDIO_HDI_INVALID_PARAM);
110 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
111 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
112 return context->proxy_->GetChannelMode(*(reinterpret_cast<AudioChannelMode *>(mode)));
113 }
114
RegCallbackInternal(struct AudioRender * render,::RenderCallback callback,void * cookie)115 static int32_t RegCallbackInternal(struct AudioRender *render, ::RenderCallback callback, void *cookie)
116 {
117 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
118 CHECK_NULL_RETURN(callback, ERR_DH_AUDIO_HDI_INVALID_PARAM);
119 CHECK_NULL_RETURN(cookie, ERR_DH_AUDIO_HDI_INVALID_PARAM);
120
121 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
122 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
123 std::lock_guard<std::mutex> lock(context->mtx_);
124 if (context->callbackInternal_ == nullptr || callback != context->callback_) {
125 context->callbackInternal_ = std::make_unique<AudioRenderCallbackContext>(callback, cookie);
126 } else {
127 return DH_SUCCESS;
128 }
129
130 if (context->callbackInternal_->callbackStub_ == nullptr) {
131 context->callbackInternal_ = nullptr;
132 return ERR_DH_AUDIO_HDI_CALL_FAILED;
133 }
134 int32_t ret = context->proxy_->RegCallback(context->callbackInternal_->callbackStub_, 0);
135 if (ret == DH_SUCCESS) {
136 context->callback_ = callback;
137 } else {
138 context->callbackInternal_ = nullptr;
139 }
140 return ret;
141 }
142
DrainBufferInternal(struct AudioRender * render,enum::AudioDrainNotifyType * type)143 static int32_t DrainBufferInternal(struct AudioRender *render, enum ::AudioDrainNotifyType *type)
144 {
145 CHECK_NULL_RETURN(render, ERR_DH_AUDIO_HDI_INVALID_PARAM);
146 CHECK_NULL_RETURN(type, ERR_DH_AUDIO_HDI_INVALID_PARAM);
147 AudioRenderContext *context = reinterpret_cast<AudioRenderContext *>(render);
148 CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
149 return context->proxy_->DrainBuffer(*(reinterpret_cast<AudioDrainNotifyType *>(type)));
150 }
151
AudioRenderContext()152 AudioRenderContext::AudioRenderContext()
153 {
154 instance_.GetLatency = GetLatencyInternal;
155 instance_.RenderFrame = RenderFrameInternal;
156 instance_.GetRenderPosition = GetRenderPositionInternal;
157 instance_.SetRenderSpeed = SetRenderSpeedInternal;
158 instance_.GetRenderSpeed = GetRenderSpeedInternal;
159 instance_.SetChannelMode = SetChannelModeInternal;
160 instance_.GetChannelMode = GetChannelModeInternal;
161 instance_.RegCallback = RegCallbackInternal;
162 instance_.DrainBuffer = DrainBufferInternal;
163 instance_.IsSupportsDrain = nullptr;
164
165 instance_.control.Start = AudioControlInternal<AudioRenderContext>::Start;
166 instance_.control.Stop = AudioControlInternal<AudioRenderContext>::Stop;
167 instance_.control.Pause = AudioControlInternal<AudioRenderContext>::Pause;
168 instance_.control.Resume = AudioControlInternal<AudioRenderContext>::Resume;
169 instance_.control.Flush = AudioControlInternal<AudioRenderContext>::Flush;
170 instance_.control.TurnStandbyMode = AudioControlInternal<AudioRenderContext>::TurnStandbyMode;
171 instance_.control.AudioDevDump = AudioControlInternal<AudioRenderContext>::AudioDevDump;
172
173 instance_.attr.GetFrameSize = AudioAttributeInternal<AudioRenderContext>::GetFrameSize;
174 instance_.attr.GetFrameCount = AudioAttributeInternal<AudioRenderContext>::GetFrameCount;
175 instance_.attr.SetSampleAttributes = AudioAttributeInternal<AudioRenderContext>::SetSampleAttributes;
176 instance_.attr.GetSampleAttributes = AudioAttributeInternal<AudioRenderContext>::GetSampleAttributes;
177 instance_.attr.GetCurrentChannelId = AudioAttributeInternal<AudioRenderContext>::GetCurrentChannelId;
178 instance_.attr.SetExtraParams = AudioAttributeInternal<AudioRenderContext>::SetExtraParams;
179 instance_.attr.GetExtraParams = AudioAttributeInternal<AudioRenderContext>::GetExtraParams;
180 instance_.attr.ReqMmapBuffer = AudioAttributeInternal<AudioRenderContext>::ReqMmapBuffer;
181 instance_.attr.GetMmapPosition = AudioAttributeInternal<AudioRenderContext>::GetMmapPosition;
182
183 instance_.scene.SelectScene = AudioSceneInternal<AudioRenderContext>::SelectScene;
184 instance_.scene.CheckSceneCapability = AudioSceneInternal<AudioRenderContext>::CheckSceneCapability;
185
186 instance_.volume.SetMute = AudioVolumeInternal<AudioRenderContext>::SetMute;
187 instance_.volume.GetMute = AudioVolumeInternal<AudioRenderContext>::GetMute;
188 instance_.volume.SetVolume = AudioVolumeInternal<AudioRenderContext>::SetVolume;
189 instance_.volume.GetVolume = AudioVolumeInternal<AudioRenderContext>::GetVolume;
190 instance_.volume.GetGainThreshold = AudioVolumeInternal<AudioRenderContext>::GetGainThreshold;
191 instance_.volume.SetGain = AudioVolumeInternal<AudioRenderContext>::SetGain;
192 instance_.volume.GetGain = AudioVolumeInternal<AudioRenderContext>::GetGain;
193
194 descHal_.portId = 0;
195 descHal_.pins = PIN_NONE;
196 }
197
~AudioRenderContext()198 AudioRenderContext::~AudioRenderContext() {}
199 } // namespace DistributedHardware
200 } // namespace OHOS