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