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 <math.h>
17#include <sys/mman.h>
18#include "hdf_base.h"
19#include "hdf_types.h"
20#include "osal_mem.h"
21#include "audio_adapter_info_common.h"
22#include "audio_common.h"
23#include "audio_interface_lib_render.h"
24#include "audio_internal.h"
25#include "audio_uhdf_log.h"
26#include "securec.h"
27
28#define HDF_LOG_TAG HDF_AUDIO_PRIMARY_IMPL
29
30#define CONFIG_OUT_LATENCY_MS 100 // unit: ms
31
32/* 1 buffer: 8000(8kHz sample rate) * 2(bytes, PCM_16_BIT) * 1(channel) */
33/* 1 frame: 1024(sample) * 2(bytes, PCM_16_BIT) * 1(channel) */
34#define CONFIG_FRAME_SIZE  (1024 * 2 * 1)
35#define FRAME_SIZE         1024
36#define CONFIG_FRAME_COUNT ((8000 * 2 * 1 + ((CONFIG_FRAME_SIZE) - 1)) / (CONFIG_FRAME_SIZE))
37
38#define DEEP_BUFFER_PLATFORM_DELAY (29 * 1000LL)
39#define LOW_LATENCY_PLATFORM_DELAY (13 * 1000LL)
40#define BITS_TO_FROMAT 3
41#define VOLUME_AVERAGE 2
42#define SEC_TO_MILLSEC 1000
43#define INTEGER_TO_DEC 10
44#define DECIMAL_PART   5
45#define RENDER_2_CHS   2
46#define PCM_8_BIT      8
47#define PCM_16_BIT     16
48
49int32_t PcmBytesToFrames(const struct AudioFrameRenderMode *frameRenderMode,
50    uint64_t bytes, uint32_t *frameCount)
51{
52    if (frameRenderMode == NULL || frameCount == NULL) {
53        AUDIO_FUNC_LOGE("Parameter error!");
54        return AUDIO_ERR_INVALID_PARAM;
55    }
56
57    uint32_t formatBits = 0;
58
59    int32_t ret = FormatToBits(frameRenderMode->attrs.format, &formatBits);
60    if (ret != HDF_SUCCESS) {
61        AUDIO_FUNC_LOGE("FormatToBits error!");
62        return ret;
63    }
64
65    /* channelCount Not greater than 4 , formatBits Not greater than 64 */
66    if (frameRenderMode->attrs.channelCount > 4 || formatBits > 64) {
67        AUDIO_FUNC_LOGE("channelCount or formatBits error!");
68        return AUDIO_ERR_INTERNAL;
69    }
70
71    uint32_t frameSize = frameRenderMode->attrs.channelCount * (formatBits >> 3); // Bit to byte >> 3
72    if (frameSize == 0) {
73        AUDIO_FUNC_LOGE("frameSize error!");
74        return AUDIO_ERR_INTERNAL;
75    }
76    *frameCount = (uint32_t)bytes / frameSize;
77    return AUDIO_SUCCESS;
78}
79
80int32_t AudioRenderStart(struct IAudioRender *handle)
81{
82    AUDIO_FUNC_LOGD("Enter.");
83    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
84    if (hwRender == NULL) {
85        AUDIO_FUNC_LOGE("The pointer is null");
86        return AUDIO_ERR_INVALID_PARAM;
87    }
88
89    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
90    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
91        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
92        return AUDIO_ERR_INTERNAL;
93    }
94    pthread_mutex_lock(&hwRender->renderParam.frameRenderMode.mutex);
95    if (hwRender->renderParam.frameRenderMode.buffer != NULL) {
96        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
97        AUDIO_FUNC_LOGE("IAudioRender already start!");
98        return AUDIO_ERR_AO_BUSY; // render is busy now
99    }
100    if (hwRender->devDataHandle == NULL) {
101        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
102        AUDIO_FUNC_LOGE("devDataHandle is null!");
103        return AUDIO_ERR_INTERNAL;
104    }
105
106    int32_t ret =
107        (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIO_DRV_PCM_IOCTRL_START);
108    if (ret < 0) {
109        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
110        AUDIO_FUNC_LOGE("AudioRenderStart SetParams FAIL");
111        return AUDIO_ERR_INTERNAL;
112    }
113
114    char *buffer = (char *)OsalMemCalloc(FRAME_DATA);
115    if (buffer == NULL) {
116        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
117        AUDIO_FUNC_LOGE("Calloc Render buffer Fail!");
118        return AUDIO_ERR_MALLOC_FAIL;
119    }
120
121    hwRender->renderParam.frameRenderMode.buffer = buffer;
122    pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
123
124    AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [%s]", __FILE__, __func__, __LINE__, "Audio Render Start");
125    return AUDIO_SUCCESS;
126}
127
128int32_t AudioRenderStop(struct IAudioRender *handle)
129{
130    AUDIO_FUNC_LOGD("Enter.");
131    int32_t ret = AUDIO_SUCCESS;
132    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
133    if (hwRender == NULL) {
134        AUDIO_FUNC_LOGE("hwRender is invalid");
135        return AUDIO_ERR_INVALID_PARAM;
136    }
137    do {
138        if (hwRender->devDataHandle == NULL) {
139            AUDIO_FUNC_LOGE("RenderStart Bind Fail!");
140            ret = AUDIO_ERR_INTERNAL;
141            break;
142        }
143
144        InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
145        if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
146            AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
147            ret = AUDIO_ERR_INTERNAL;
148            break;
149        }
150        ret =
151            (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIO_DRV_PCM_IOCTRL_STOP);
152        hwRender->renderParam.renderMode.ctlParam.turnStandbyStatus = AUDIO_TURN_STANDBY_LATER;
153        if (ret < 0) {
154            AUDIO_FUNC_LOGE("AudioRenderStop SetParams FAIL");
155            ret = AUDIO_ERR_INTERNAL;
156            break;
157        }
158    } while (0);
159
160    pthread_mutex_lock(&hwRender->renderParam.frameRenderMode.mutex);
161    if (hwRender->renderParam.frameRenderMode.buffer != NULL) {
162        AudioMemFree((void **)&hwRender->renderParam.frameRenderMode.buffer);
163    } else {
164        AUDIO_FUNC_LOGE("Repeat invalid stop operation!");
165        ret = AUDIO_ERR_NOT_SUPPORT;
166    }
167    pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
168
169    AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [%s]", __FILE__, __func__, __LINE__, "Audio Render Stop");
170    return ret;
171}
172
173int32_t AudioRenderPause(struct IAudioRender *handle)
174{
175    AUDIO_FUNC_LOGD("Enter.");
176    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
177    if (hwRender == NULL) {
178        AUDIO_FUNC_LOGE("hwRender is null");
179        return AUDIO_ERR_INVALID_PARAM;
180    }
181    pthread_mutex_lock(&hwRender->renderParam.frameRenderMode.mutex);
182    if (hwRender->renderParam.frameRenderMode.buffer == NULL) {
183        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
184        AUDIO_FUNC_LOGE("IAudioRender already stop!");
185        return AUDIO_ERR_INTERNAL;
186    }
187    pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
188    if (hwRender->renderParam.renderMode.ctlParam.pause) {
189        AUDIO_FUNC_LOGE("Audio is already pause!");
190        return AUDIO_ERR_NOT_SUPPORT;
191    }
192    if (hwRender->devDataHandle == NULL) {
193        AUDIO_FUNC_LOGE("RenderPause Bind Fail!");
194        return AUDIO_ERR_INTERNAL;
195    }
196
197    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
198    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
199        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
200        return AUDIO_ERR_INTERNAL;
201    }
202
203    bool pauseStatus = hwRender->renderParam.renderMode.ctlParam.pause;
204
205    hwRender->renderParam.renderMode.ctlParam.pause = true;
206    int32_t ret =
207        (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_PAUSE_WRITE);
208    if (ret < 0) {
209        AUDIO_FUNC_LOGE("RenderPause FAIL!");
210        hwRender->renderParam.renderMode.ctlParam.pause = pauseStatus;
211        return AUDIO_ERR_INTERNAL;
212    }
213
214    AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [%s]", __FILE__, __func__, __LINE__, "Audio Render Pause");
215    return AUDIO_SUCCESS;
216}
217
218int32_t AudioRenderResume(struct IAudioRender *handle)
219{
220    AUDIO_FUNC_LOGD("Enter.");
221    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
222    if (hwRender == NULL) {
223        AUDIO_FUNC_LOGE("Param is error");
224        return AUDIO_ERR_INVALID_PARAM;
225    }
226    if (!hwRender->renderParam.renderMode.ctlParam.pause) {
227        AUDIO_FUNC_LOGE("Audio is already Resume !");
228        return AUDIO_ERR_NOT_SUPPORT;
229    }
230    if (hwRender->devDataHandle == NULL) {
231        AUDIO_FUNC_LOGE("RenderResume Bind Fail!");
232        return AUDIO_ERR_INTERNAL;
233    }
234
235    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
236    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
237        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
238        return AUDIO_ERR_INTERNAL;
239    }
240
241    bool resumeStatus = hwRender->renderParam.renderMode.ctlParam.pause;
242
243    hwRender->renderParam.renderMode.ctlParam.pause = false;
244    int32_t ret =
245        (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_PAUSE_WRITE);
246    if (ret < 0) {
247        AUDIO_FUNC_LOGE("RenderResume FAIL!");
248        hwRender->renderParam.renderMode.ctlParam.pause = resumeStatus;
249        return AUDIO_ERR_INTERNAL;
250    }
251
252    AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [%s]", __FILE__, __func__, __LINE__, "Audio Render Resume");
253    return AUDIO_SUCCESS;
254}
255
256int32_t AudioRenderFlush(struct IAudioRender *handle)
257{
258    AUDIO_FUNC_LOGD("Enter.");
259    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
260    if (hwRender == NULL) {
261        AUDIO_FUNC_LOGE("Param is error");
262        return AUDIO_ERR_INVALID_PARAM;
263    }
264
265    bool callBackStatus = hwRender->renderParam.renderMode.hwInfo.callBackEnable;
266    if (callBackStatus) {
267        return CallbackProcessing(hwRender, AUDIO_FLUSH_COMPLETED);
268    }
269    return AUDIO_ERR_NOT_SUPPORT;
270}
271
272int32_t AudioRenderGetFrameSize(struct IAudioRender *handle, uint64_t *size)
273{
274    AUDIO_FUNC_LOGD("Enter.");
275    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
276    if (hwRender == NULL || size == NULL) {
277        AUDIO_FUNC_LOGE("Param is error");
278        return AUDIO_ERR_INVALID_PARAM;
279    }
280
281    uint32_t channelCount = hwRender->renderParam.frameRenderMode.attrs.channelCount;
282    enum AudioFormat format = hwRender->renderParam.frameRenderMode.attrs.format;
283
284    uint32_t formatBits = 0;
285    int32_t ret = FormatToBits(format, &formatBits);
286    if (ret != AUDIO_SUCCESS) {
287        return ret;
288    }
289    *size = FRAME_SIZE * channelCount * (formatBits >> BITS_TO_FROMAT);
290    return AUDIO_SUCCESS;
291}
292
293int32_t AudioRenderGetFrameCount(struct IAudioRender *handle, uint64_t *count)
294{
295    AUDIO_FUNC_LOGD("Enter.");
296    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
297    if (hwRender == NULL || count == NULL) {
298        AUDIO_FUNC_LOGE("Param is error");
299        return AUDIO_ERR_INVALID_PARAM;
300    }
301    *count = hwRender->renderParam.frameRenderMode.frames;
302    return AUDIO_SUCCESS;
303}
304
305int32_t AudioRenderSetSampleAttributes(struct IAudioRender *handle, const struct AudioSampleAttributes *attrs)
306{
307    AUDIO_FUNC_LOGD("Enter.");
308    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
309    if (hwRender == NULL || attrs == NULL || hwRender->devDataHandle == NULL) {
310        AUDIO_FUNC_LOGE("Param is error");
311        return AUDIO_ERR_INVALID_PARAM;
312    }
313
314    int32_t ret = AudioCheckParaAttr(attrs);
315    if (ret != AUDIO_SUCCESS) {
316        return ret;
317    }
318
319    /* attrs temp */
320    struct AudioSampleAttributes tempAttrs = hwRender->renderParam.frameRenderMode.attrs;
321    hwRender->renderParam.frameRenderMode.attrs = *attrs;
322
323    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
324    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL || hwRender->devDataHandle == NULL) {
325        hwRender->renderParam.frameRenderMode.attrs = tempAttrs;
326        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
327        return AUDIO_ERR_INTERNAL;
328    }
329
330    ret = (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIO_DRV_PCM_IOCTL_HW_PARAMS);
331    if (ret < 0) {
332        AUDIO_FUNC_LOGE("SetSampleAttributes FAIL");
333        hwRender->renderParam.frameRenderMode.attrs = tempAttrs;
334        return AUDIO_ERR_INTERNAL;
335    }
336    return AUDIO_SUCCESS;
337}
338
339int32_t AudioRenderGetSampleAttributes(struct IAudioRender *handle, struct AudioSampleAttributes *attrs)
340{
341    AUDIO_FUNC_LOGD("Enter.");
342    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
343    if (hwRender == NULL || attrs == NULL) {
344        AUDIO_FUNC_LOGE("Param is error");
345        return AUDIO_ERR_INVALID_PARAM;
346    }
347
348    attrs->format = hwRender->renderParam.frameRenderMode.attrs.format;
349    attrs->sampleRate = hwRender->renderParam.frameRenderMode.attrs.sampleRate;
350    attrs->channelCount = hwRender->renderParam.frameRenderMode.attrs.channelCount;
351    attrs->type = hwRender->renderParam.frameRenderMode.attrs.type;
352    attrs->interleaved = hwRender->renderParam.frameRenderMode.attrs.interleaved;
353    attrs->period = hwRender->renderParam.frameRenderMode.attrs.period;
354    attrs->frameSize = hwRender->renderParam.frameRenderMode.attrs.frameSize;
355    attrs->isBigEndian = hwRender->renderParam.frameRenderMode.attrs.isBigEndian;
356    attrs->isSignedData = hwRender->renderParam.frameRenderMode.attrs.isSignedData;
357    attrs->startThreshold = hwRender->renderParam.frameRenderMode.attrs.startThreshold;
358    attrs->stopThreshold = hwRender->renderParam.frameRenderMode.attrs.stopThreshold;
359    attrs->silenceThreshold = hwRender->renderParam.frameRenderMode.attrs.silenceThreshold;
360    return AUDIO_SUCCESS;
361}
362
363int32_t AudioRenderGetCurrentChannelId(struct IAudioRender *handle, uint32_t *channelId)
364{
365    AUDIO_FUNC_LOGD("Enter.");
366    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
367    if (hwRender == NULL || channelId == NULL) {
368        AUDIO_FUNC_LOGE("Param is error");
369        return AUDIO_ERR_INVALID_PARAM;
370    }
371    *channelId = hwRender->renderParam.frameRenderMode.attrs.channelCount;
372    return AUDIO_SUCCESS;
373}
374
375int32_t AudioRenderCheckSceneCapability(
376    struct IAudioRender *handle, const struct AudioSceneDescriptor *scene, bool *supported)
377{
378    AUDIO_FUNC_LOGD("Enter.");
379    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
380    if (hwRender == NULL || scene == NULL || supported == NULL) {
381        AUDIO_FUNC_LOGE("Param is error");
382        return AUDIO_ERR_INVALID_PARAM;
383    }
384#ifndef AUDIO_HAL_NOTSUPPORT_PATHSELECT
385    *supported = false;
386    /* Temporary storage does not save the structure */
387    struct AudioHwRenderParam renderParam = hwRender->renderParam;
388    renderParam.frameRenderMode.attrs.type = (enum AudioCategory)scene->scene.id;
389    renderParam.renderMode.hwInfo.deviceDescript.pins = scene->desc.pins;
390
391    PathSelAnalysisJson *pPathSelAnalysisJson = AudioPassthroughGetPathSelAnalysisJson();
392    if (pPathSelAnalysisJson == NULL) {
393        AUDIO_FUNC_LOGE("pPathSelAnalysisJson Is NULL!");
394        return AUDIO_ERR_NOT_SUPPORT;
395    }
396
397    int32_t ret = (*pPathSelAnalysisJson)((void *)&renderParam, CHECKSCENE_PATH_SELECT);
398    if (ret < 0) {
399        if (ret == AUDIO_ERR_NOT_SUPPORT) {
400            AUDIO_FUNC_LOGE("AudioRenderCheckSceneCapability not Support!");
401            return AUDIO_ERR_NOT_SUPPORT;
402        } else {
403            AUDIO_FUNC_LOGE("AudioRenderCheckSceneCapability fail!");
404            return AUDIO_ERR_INTERNAL;
405        }
406    }
407    *supported = true;
408    return AUDIO_SUCCESS;
409#else
410    return AUDIO_ERR_NOT_SUPPORT;
411#endif
412}
413
414int32_t AudioRenderSelectScene(struct IAudioRender *handle, const struct AudioSceneDescriptor *scene)
415{
416    AUDIO_FUNC_LOGD("Enter.");
417    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
418    if (hwRender == NULL || scene == NULL) {
419        AUDIO_FUNC_LOGE("Param is error");
420        return AUDIO_ERR_INVALID_PARAM;
421    }
422    if (hwRender->devCtlHandle == NULL) {
423        AUDIO_FUNC_LOGE("RenderSelectScene Bind Fail!");
424        return AUDIO_ERR_INTERNAL;
425    }
426#ifndef AUDIO_HAL_NOTSUPPORT_PATHSELECT
427    PathSelAnalysisJson *pPathSelAnalysisJson = AudioPassthroughGetPathSelAnalysisJson();
428    if (pPathSelAnalysisJson == NULL) {
429        AUDIO_FUNC_LOGE("pPathSelAnalysisJson Is NULL!");
430        return AUDIO_ERR_NOT_SUPPORT;
431    }
432    enum AudioCategory sceneId = hwRender->renderParam.frameRenderMode.attrs.type;
433    enum AudioPortPin descPins = hwRender->renderParam.renderMode.hwInfo.deviceDescript.pins;
434
435    hwRender->renderParam.frameRenderMode.attrs.type = (enum AudioCategory)(scene->scene.id);
436    hwRender->renderParam.renderMode.hwInfo.deviceDescript.pins = scene->desc.pins;
437    if ((*pPathSelAnalysisJson)((void *)&hwRender->renderParam, RENDER_PATH_SELECT) < 0) {
438        AUDIO_FUNC_LOGE("AudioRenderSelectScene Fail!");
439        hwRender->renderParam.frameRenderMode.attrs.type = sceneId;
440        hwRender->renderParam.renderMode.hwInfo.deviceDescript.pins = descPins;
441        return AUDIO_ERR_INTERNAL;
442    }
443
444    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
445    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
446        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
447        hwRender->renderParam.frameRenderMode.attrs.type = sceneId;
448        hwRender->renderParam.renderMode.hwInfo.deviceDescript.pins = descPins;
449        return AUDIO_ERR_INTERNAL;
450    }
451
452    int32_t ret = (*pInterfaceLibModeRender)(
453        hwRender->devCtlHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_SCENESELECT_WRITE);
454    if (ret < 0) {
455        AUDIO_FUNC_LOGE("SetParams FAIL!");
456        hwRender->renderParam.frameRenderMode.attrs.type = sceneId;
457        hwRender->renderParam.renderMode.hwInfo.deviceDescript.pins = descPins;
458        return AUDIO_ERR_INTERNAL;
459    }
460    return AUDIO_SUCCESS;
461#else
462    return AUDIO_ERR_NOT_SUPPORT;
463#endif
464}
465
466int32_t AudioRenderSetMute(struct IAudioRender *handle, bool mute)
467{
468    AUDIO_FUNC_LOGD("Enter.");
469    struct AudioHwRender *impl = (struct AudioHwRender *)handle;
470    if (impl == NULL) {
471        AUDIO_FUNC_LOGE("impl is error");
472        return AUDIO_ERR_INVALID_PARAM;
473    }
474    if (impl->devCtlHandle == NULL) {
475        AUDIO_FUNC_LOGE("RenderSetMute Bind Fail!");
476        return AUDIO_ERR_INTERNAL;
477    }
478
479    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
480    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
481        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
482        return AUDIO_ERR_INTERNAL;
483    }
484
485    bool muteStatus = impl->renderParam.renderMode.ctlParam.mute;
486    impl->renderParam.renderMode.ctlParam.mute = mute;
487
488    int32_t ret = (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_MUTE_WRITE);
489    if (ret < 0) {
490        AUDIO_FUNC_LOGE("SetMute SetParams FAIL");
491        impl->renderParam.renderMode.ctlParam.mute = muteStatus;
492        return AUDIO_ERR_INTERNAL;
493    }
494    AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [Setmute = %d]", __FILE__, __func__, __LINE__, mute);
495    return AUDIO_SUCCESS;
496}
497
498int32_t AudioRenderGetMute(struct IAudioRender *handle, bool *mute)
499{
500    AUDIO_FUNC_LOGD("Enter.");
501    struct AudioHwRender *impl = (struct AudioHwRender *)handle;
502    if (impl == NULL || mute == NULL) {
503        AUDIO_FUNC_LOGE("RenderGetMute Bind Fail!");
504        return AUDIO_ERR_INVALID_PARAM;
505    }
506
507    if (impl->devCtlHandle == NULL) {
508        AUDIO_FUNC_LOGE("RenderGetMute Bind Fail!");
509        return AUDIO_ERR_INTERNAL;
510    }
511
512    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
513    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
514        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
515        return AUDIO_ERR_INTERNAL;
516    }
517
518    int32_t ret =
519        (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_MUTE_READ);
520    if (ret < 0) {
521        AUDIO_FUNC_LOGE("Get Mute FAIL!");
522        return AUDIO_ERR_INTERNAL;
523    }
524    *mute = impl->renderParam.renderMode.ctlParam.mute;
525    AUDIO_FUNC_LOGI("GetMute SUCCESS!");
526    return AUDIO_SUCCESS;
527}
528
529int32_t AudioRenderSetVolume(struct IAudioRender *handle, float volume)
530{
531    AUDIO_FUNC_LOGD("Enter.");
532    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
533    if (hwRender == NULL) {
534        AUDIO_FUNC_LOGE("hwRender is error");
535        return AUDIO_ERR_INVALID_PARAM;
536    }
537
538    float volumeTemp = hwRender->renderParam.renderMode.ctlParam.volume;
539    float volMax = (float)hwRender->renderParam.renderMode.ctlParam.volThreshold.volMax;
540    float volMin = (float)hwRender->renderParam.renderMode.ctlParam.volThreshold.volMin;
541    if (volume < 0 || volume > 1) {
542        AUDIO_FUNC_LOGE("volume param Is error!");
543        return AUDIO_ERR_INVALID_PARAM;
544    }
545    if (hwRender->devCtlHandle == NULL) {
546        AUDIO_FUNC_LOGE("RenderSetVolume Bind Fail!");
547        return AUDIO_ERR_INTERNAL;
548    }
549
550    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
551    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
552        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
553        return AUDIO_ERR_INTERNAL;
554    }
555
556    volume = (volume == 0) ? 1 : (volume * VOLUME_CHANGE);
557    /* change volume to db */
558    float volTemp = ((volMax - volMin) / 2) * log10(volume) + volMin;
559    if (volTemp < volMin || volTemp > volMax) {
560        AUDIO_FUNC_LOGE("volTemp fail");
561        return AUDIO_ERR_INTERNAL;
562    }
563    hwRender->renderParam.renderMode.ctlParam.volume = volTemp;
564
565    int32_t ret =
566        (*pInterfaceLibModeRender)(hwRender->devCtlHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_ELEM_WRITE);
567    if (ret < 0) {
568        AUDIO_FUNC_LOGE("RenderSetVolume FAIL!");
569        hwRender->renderParam.renderMode.ctlParam.volume = volumeTemp;
570        return AUDIO_ERR_INTERNAL;
571    }
572    return AUDIO_SUCCESS;
573}
574
575int32_t AudioRenderGetVolume(struct IAudioRender *handle, float *volume)
576{
577    AUDIO_FUNC_LOGD("Enter.");
578    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
579    if (hwRender == NULL || volume == NULL) {
580        AUDIO_FUNC_LOGE("Param is error");
581        return AUDIO_ERR_INVALID_PARAM;
582    }
583    if (hwRender->devCtlHandle == NULL) {
584        AUDIO_FUNC_LOGE("RenderGetVolume Bind Fail!");
585        return AUDIO_ERR_INTERNAL;
586    }
587
588    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
589    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
590        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
591        return AUDIO_ERR_INTERNAL;
592    }
593
594    int32_t ret =
595        (*pInterfaceLibModeRender)(hwRender->devCtlHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_ELEM_READ);
596    if (ret < 0) {
597        AUDIO_FUNC_LOGE("RenderGetVolume FAIL!");
598        return AUDIO_ERR_INTERNAL;
599    }
600
601    float volumeTemp = hwRender->renderParam.renderMode.ctlParam.volume;
602    float volMax = (float)hwRender->renderParam.renderMode.ctlParam.volThreshold.volMax;
603    float volMin = (float)hwRender->renderParam.renderMode.ctlParam.volThreshold.volMin;
604    if ((volMax - volMin) == 0) {
605        AUDIO_FUNC_LOGE("Divisor cannot be zero!");
606        return AUDIO_ERR_INTERNAL;
607    }
608
609    volumeTemp = (volumeTemp - volMin) / ((volMax - volMin) / VOLUME_AVERAGE);
610
611    int volumeT = (int)((pow(INTEGER_TO_DEC, volumeTemp) + DECIMAL_PART) / INTEGER_TO_DEC); // delet 0.X num
612
613    *volume = (float)volumeT / INTEGER_TO_DEC;                                               // get volume (0-1)
614    return AUDIO_SUCCESS;
615}
616
617int32_t AudioRenderGetGainThreshold(struct IAudioRender *handle, float *min, float *max)
618{
619    AUDIO_FUNC_LOGD("Enter.");
620    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
621    if (hwRender == NULL || min == NULL || max == NULL) {
622        return AUDIO_ERR_INVALID_PARAM;
623    }
624    if (hwRender->devCtlHandle == NULL) {
625        AUDIO_FUNC_LOGE("RenderGetGainThreshold Bind Fail!");
626        return AUDIO_ERR_INTERNAL;
627    }
628
629    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
630    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
631        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
632        return AUDIO_ERR_INTERNAL;
633    }
634
635    int32_t ret = (*pInterfaceLibModeRender)(
636        hwRender->devCtlHandle, &hwRender->renderParam, AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_READ);
637    if (ret < 0) {
638        AUDIO_FUNC_LOGE("GetGainThreshold FAIL!");
639        return AUDIO_ERR_INTERNAL;
640    }
641
642    *max = hwRender->renderParam.renderMode.ctlParam.audioGain.gainMax;
643    *min = hwRender->renderParam.renderMode.ctlParam.audioGain.gainMin;
644    return AUDIO_SUCCESS;
645}
646
647int32_t AudioRenderGetGain(struct IAudioRender *handle, float *gain)
648{
649    AUDIO_FUNC_LOGD("Enter.");
650    struct AudioHwRender *impl = (struct AudioHwRender *)handle;
651    if (impl == NULL || gain == NULL) {
652        AUDIO_FUNC_LOGE("Param is error");
653        return AUDIO_ERR_INVALID_PARAM;
654    }
655    if (impl->devCtlHandle == NULL) {
656        AUDIO_FUNC_LOGE("RenderGetGain Bind Fail!");
657        return AUDIO_ERR_INTERNAL;
658    }
659
660    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
661    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
662        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
663        return AUDIO_ERR_INTERNAL;
664    }
665
666    int32_t ret =
667        (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_GAIN_READ);
668    if (ret < 0) {
669        AUDIO_FUNC_LOGE("RenderGetGain FAIL");
670        return AUDIO_ERR_INTERNAL;
671    }
672
673    *gain = impl->renderParam.renderMode.ctlParam.audioGain.gain;
674    return AUDIO_SUCCESS;
675}
676
677int32_t AudioRenderSetGain(struct IAudioRender *handle, float gain)
678{
679    AUDIO_FUNC_LOGD("Enter.");
680    int32_t ret = 0;
681    struct AudioHwRender *impl = (struct AudioHwRender *)handle;
682    if (impl == NULL || gain < 0) {
683        AUDIO_FUNC_LOGE("Param is error");
684        return AUDIO_ERR_INVALID_PARAM;
685    }
686
687    float gainTemp = impl->renderParam.renderMode.ctlParam.audioGain.gain;
688    impl->renderParam.renderMode.ctlParam.audioGain.gain = gain;
689    if (impl->devCtlHandle == NULL) {
690        AUDIO_FUNC_LOGE("RenderSetGain Bind Fail!");
691        impl->renderParam.renderMode.ctlParam.audioGain.gain = gainTemp;
692        return AUDIO_ERR_INTERNAL;
693    }
694
695    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
696    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
697        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
698        impl->renderParam.renderMode.ctlParam.audioGain.gain = gainTemp;
699        return AUDIO_ERR_INTERNAL;
700    }
701
702    ret = (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_GAIN_WRITE);
703    if (ret < 0) {
704        AUDIO_FUNC_LOGE("RenderSetGain FAIL");
705        impl->renderParam.renderMode.ctlParam.audioGain.gain = gainTemp;
706        return AUDIO_ERR_INTERNAL;
707    }
708    return AUDIO_SUCCESS;
709}
710
711int32_t AudioRenderGetLatency(struct IAudioRender *render, uint32_t *ms)
712{
713    AUDIO_FUNC_LOGD("Enter.");
714    struct AudioHwRender *impl = (struct AudioHwRender *)render;
715    if (impl == NULL || ms == NULL) {
716        AUDIO_FUNC_LOGE("impl or ms is null!");
717        return AUDIO_ERR_INVALID_PARAM;
718    }
719
720    uint32_t byteRate = impl->renderParam.frameRenderMode.byteRate;
721    uint32_t periodSize = impl->renderParam.frameRenderMode.periodSize;
722
723    if (byteRate == 0) {
724        AUDIO_FUNC_LOGE("byteRate error!");
725        return AUDIO_ERR_INTERNAL;
726    }
727
728    *ms = (periodSize * SEC_TO_MILLSEC) / (byteRate * RENDER_2_CHS * PCM_16_BIT / PCM_8_BIT);
729    return AUDIO_SUCCESS;
730}
731
732static int32_t LogErrorGetRensonAndTime(struct AudioHwRender *hwRender, int errorReason)
733{
734    if (hwRender == NULL) {
735        AUDIO_FUNC_LOGE("hwRender is null!");
736        return AUDIO_ERR_INVALID_PARAM;
737    }
738
739    if (hwRender->errorLog.iter >= ERROR_LOG_MAX_NUM) {
740        AUDIO_FUNC_LOGE("hwRender->errorLog.iter >= ERROR_LOG_MAX_NUM error!");
741        return AUDIO_ERR_INVALID_PARAM;
742    }
743
744    if (hwRender->errorLog.errorDump[hwRender->errorLog.iter].reason == NULL) {
745        hwRender->errorLog.errorDump[hwRender->errorLog.iter].reason = (char *)OsalMemCalloc(ERROR_REASON_DESC_LEN);
746        if (hwRender->errorLog.errorDump[hwRender->errorLog.iter].reason == NULL) {
747            AUDIO_FUNC_LOGE("Calloc reasonDesc Fail!");
748            return AUDIO_ERR_MALLOC_FAIL;
749        }
750    }
751
752    if (hwRender->errorLog.errorDump[hwRender->errorLog.iter].currentTime == NULL) {
753        hwRender->errorLog.errorDump[hwRender->errorLog.iter].currentTime =
754            (char *)OsalMemCalloc(ERROR_REASON_DESC_LEN);
755        if (hwRender->errorLog.errorDump[hwRender->errorLog.iter].currentTime == NULL) {
756            AUDIO_FUNC_LOGE("Calloc time Fail!");
757            return AUDIO_ERR_MALLOC_FAIL;
758        }
759    }
760
761    memset_s(
762        hwRender->errorLog.errorDump[hwRender->errorLog.iter].reason, ERROR_REASON_DESC_LEN, 0, ERROR_REASON_DESC_LEN);
763    memset_s(hwRender->errorLog.errorDump[hwRender->errorLog.iter].currentTime, ERROR_REASON_DESC_LEN, 0,
764        ERROR_REASON_DESC_LEN);
765
766    int32_t ret = GetErrorReason(errorReason, hwRender->errorLog.errorDump[hwRender->errorLog.iter].reason);
767    if (ret < 0) {
768        AUDIO_FUNC_LOGE("GetErrorReason failed!");
769        return AUDIO_ERR_INTERNAL;
770    }
771
772    ret = GetCurrentTime(hwRender->errorLog.errorDump[hwRender->errorLog.iter].currentTime);
773    if (ret < 0) {
774        AUDIO_FUNC_LOGE("GetCurrentTime Fail");
775        return AUDIO_ERR_INTERNAL;
776    }
777    return AUDIO_SUCCESS;
778}
779
780static void LogError(AudioHandle handle, int32_t errorCode, int reason)
781{
782    struct AudioHwRender *hwRender = (struct AudioHwRender *)handle;
783    if (hwRender == NULL) {
784        AUDIO_FUNC_LOGE("hwRender is null!");
785        return;
786    }
787
788    hwRender->errorLog.totalErrors++;
789    if (hwRender->errorLog.iter >= ERROR_LOG_MAX_NUM) {
790        hwRender->errorLog.iter = 0;
791    }
792
793    int32_t ret = LogErrorGetRensonAndTime(hwRender, reason);
794    if (ret < 0) {
795        AUDIO_FUNC_LOGE("LogErrorGetRensonAndTime error!");
796        return;
797    }
798
799    if (errorCode == WRITE_FRAME_ERROR_CODE) {
800        hwRender->errorLog.errorDump[hwRender->errorLog.iter].errorCode = errorCode;
801        hwRender->errorLog.errorDump[hwRender->errorLog.iter].count = hwRender->errorLog.iter;
802        hwRender->errorLog.errorDump[hwRender->errorLog.iter].frames = hwRender->renderParam.frameRenderMode.frames;
803        hwRender->errorLog.iter++;
804    }
805}
806
807static int32_t AudioRenderRenderFramSplit(struct AudioHwRender *hwRender)
808{
809    if (hwRender == NULL) {
810        AUDIO_FUNC_LOGE("hwRender is null!");
811        return HDF_FAILURE;
812    }
813
814    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
815    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
816        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
817        return HDF_FAILURE;
818    }
819    if (hwRender->devDataHandle == NULL) {
820        AUDIO_FUNC_LOGE("hwRender->devDataHandle is null!");
821        return HDF_FAILURE;
822    }
823
824    int32_t ret =
825        (*pInterfaceLibModeRender)(hwRender->devDataHandle, &hwRender->renderParam, AUDIO_DRV_PCM_IOCTL_WRITE);
826    if (ret < 0) {
827        AUDIO_FUNC_LOGE("Render Frame FAIL!");
828        LogError((AudioHandle)hwRender, WRITE_FRAME_ERROR_CODE, ret);
829        return AUDIO_ERR_INTERNAL;
830    }
831    return HDF_SUCCESS;
832}
833
834int32_t AudioRenderRenderFrame(
835    struct IAudioRender *render, const int8_t *frame, uint32_t frameLen, uint64_t *replyBytes)
836{
837    struct AudioHwRender *hwRender = (struct AudioHwRender *)render;
838    if (hwRender == NULL || frame == NULL || replyBytes == NULL) {
839        AUDIO_FUNC_LOGE("Render Frame Paras is NULL!");
840        return AUDIO_ERR_INVALID_PARAM;
841    }
842    if (frameLen > FRAME_DATA) {
843        AUDIO_FUNC_LOGE("Out of FRAME_DATA size!");
844        return AUDIO_ERR_INTERNAL;
845    }
846    pthread_mutex_lock(&hwRender->renderParam.frameRenderMode.mutex);
847    if (hwRender->renderParam.frameRenderMode.buffer == NULL) {
848        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
849        AUDIO_FUNC_LOGE("Render Frame buffer is NULL!");
850        return AUDIO_ERR_INVALID_PARAM;
851    }
852
853    int32_t ret = memcpy_s(hwRender->renderParam.frameRenderMode.buffer, FRAME_DATA, frame, frameLen);
854    if (ret != EOK) {
855        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
856        AUDIO_FUNC_LOGE("memcpy_s fail");
857        return AUDIO_ERR_INTERNAL;
858    }
859
860    hwRender->renderParam.frameRenderMode.bufferSize = (uint64_t)frameLen;
861    uint32_t frameCount = 0;
862    if (PcmBytesToFrames(&hwRender->renderParam.frameRenderMode, (uint64_t)frameLen, &frameCount) != AUDIO_SUCCESS) {
863        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
864        AUDIO_FUNC_LOGE("PcmBytesToFrames error!");
865        return AUDIO_ERR_INTERNAL;
866    }
867
868    hwRender->renderParam.frameRenderMode.bufferFrameSize = (uint64_t)frameCount;
869    if (AudioRenderRenderFramSplit(hwRender) < 0) {
870        pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
871        AUDIO_FUNC_LOGE("AudioRenderRenderFramSplit error!");
872        return AUDIO_ERR_INTERNAL;
873    }
874
875    pthread_mutex_unlock(&hwRender->renderParam.frameRenderMode.mutex);
876
877    *replyBytes = (uint64_t)frameLen;
878
879    hwRender->renderParam.frameRenderMode.frames += hwRender->renderParam.frameRenderMode.bufferFrameSize;
880    if (hwRender->renderParam.frameRenderMode.attrs.sampleRate == 0) {
881        AUDIO_FUNC_LOGE("Divisor cannot be zero!");
882        return AUDIO_ERR_INTERNAL;
883    }
884
885    if (TimeToAudioTimeStamp(hwRender->renderParam.frameRenderMode.bufferFrameSize,
886        &hwRender->renderParam.frameRenderMode.time,
887        hwRender->renderParam.frameRenderMode.attrs.sampleRate) == HDF_FAILURE) {
888        AUDIO_FUNC_LOGE("Frame is NULL");
889        return AUDIO_ERR_INTERNAL;
890    }
891    return AUDIO_SUCCESS;
892}
893
894int32_t AudioRenderGetRenderPosition(struct IAudioRender *render, uint64_t *frames, struct AudioTimeStamp *time)
895{
896    AUDIO_FUNC_LOGD("Enter.");
897    struct AudioHwRender *impl = (struct AudioHwRender *)render;
898    if (impl == NULL || frames == NULL || time == NULL) {
899        AUDIO_FUNC_LOGE("Paras is NULL!");
900        return AUDIO_ERR_INVALID_PARAM;
901    }
902    *frames = impl->renderParam.frameRenderMode.frames;
903    *time = impl->renderParam.frameRenderMode.time;
904    return AUDIO_SUCCESS;
905}
906
907int32_t AudioRenderSetRenderSpeed(struct IAudioRender *render, float speed)
908{
909    AUDIO_FUNC_LOGD("Enter.");
910    (void)speed;
911    struct AudioHwRender *hwRender = (struct AudioHwRender *)render;
912    if (hwRender == NULL) {
913        AUDIO_FUNC_LOGE("hwRender is NULL!");
914        return AUDIO_ERR_INVALID_PARAM;
915    }
916    return AUDIO_ERR_NOT_SUPPORT;
917}
918
919int32_t AudioRenderGetRenderSpeed(struct IAudioRender *render, float *speed)
920{
921    AUDIO_FUNC_LOGD("Enter.");
922    struct AudioHwRender *hwRender = (struct AudioHwRender *)render;
923    if (hwRender == NULL || speed == NULL) {
924        AUDIO_FUNC_LOGE("Param is NULL!");
925        return AUDIO_ERR_INVALID_PARAM;
926    }
927    return AUDIO_ERR_NOT_SUPPORT;
928}
929
930int32_t AudioRenderSetChannelMode(struct IAudioRender *render, enum AudioChannelMode mode)
931{
932    AUDIO_FUNC_LOGD("Enter.");
933    struct AudioHwRender *impl = (struct AudioHwRender *)render;
934    if (impl == NULL) {
935        AUDIO_FUNC_LOGE("impl is NULL!");
936        return AUDIO_ERR_INVALID_PARAM;
937    }
938
939    if (impl->devCtlHandle == NULL) {
940        AUDIO_FUNC_LOGE("Bind Fail!");
941        return AUDIO_ERR_INTERNAL;
942    }
943
944    enum AudioChannelMode tempMode = impl->renderParam.frameRenderMode.mode;
945    impl->renderParam.frameRenderMode.mode = mode;
946
947    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
948    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
949        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
950        impl->renderParam.frameRenderMode.mode = tempMode;
951        return AUDIO_ERR_INTERNAL;
952    }
953
954    int32_t ret =
955        (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_CHANNEL_MODE_WRITE);
956    if (ret < 0) {
957        AUDIO_FUNC_LOGE("Set ChannelMode FAIL!");
958        impl->renderParam.frameRenderMode.mode = tempMode;
959        return AUDIO_ERR_INTERNAL;
960    }
961    return AUDIO_SUCCESS;
962}
963
964int32_t AudioRenderGetChannelMode(struct IAudioRender *render, enum AudioChannelMode *mode)
965{
966    AUDIO_FUNC_LOGD("Enter.");
967    struct AudioHwRender *impl = (struct AudioHwRender *)render;
968    if (impl == NULL || mode == NULL || impl->devCtlHandle == NULL) {
969        AUDIO_FUNC_LOGE("Paras is NULL!");
970        return AUDIO_ERR_INVALID_PARAM;
971    }
972
973    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
974    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
975        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
976        return AUDIO_ERR_INTERNAL;
977    }
978
979    int32_t ret =
980        (*pInterfaceLibModeRender)(impl->devCtlHandle, &impl->renderParam, AUDIODRV_CTL_IOCTL_CHANNEL_MODE_READ);
981    if (ret < 0) {
982        AUDIO_FUNC_LOGE("Get ChannelMode FAIL!");
983        return AUDIO_ERR_INTERNAL;
984    }
985    *mode = impl->renderParam.frameRenderMode.mode;
986    return AUDIO_SUCCESS;
987}
988
989static int32_t SetValue(struct ExtraParams mExtraParams, struct AudioHwRender *render)
990{
991    if (render == NULL) {
992        AUDIO_FUNC_LOGE("render is NULL!");
993        return HDF_FAILURE;
994    }
995    if (mExtraParams.route != -1) {
996        render->renderParam.renderMode.hwInfo.pathroute = mExtraParams.route;
997    }
998    if (mExtraParams.format != -1) {
999        render->renderParam.frameRenderMode.attrs.format = mExtraParams.format;
1000    }
1001    if (mExtraParams.channels != 0) {
1002        render->renderParam.frameRenderMode.attrs.channelCount = mExtraParams.channels;
1003    }
1004    if (mExtraParams.flag) {
1005        render->renderParam.frameRenderMode.frames = mExtraParams.frames;
1006    }
1007    if (mExtraParams.sampleRate != 0) {
1008        render->renderParam.frameRenderMode.attrs.sampleRate = mExtraParams.sampleRate;
1009    }
1010    return HDF_SUCCESS;
1011}
1012
1013int32_t AudioRenderSetExtraParams(struct IAudioRender *handle, const char *keyValueList)
1014{
1015    AUDIO_FUNC_LOGD("Enter.");
1016    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1017    if (render == NULL || keyValueList == NULL) {
1018        return AUDIO_ERR_INVALID_PARAM;
1019    }
1020    int32_t count = 0;
1021    int32_t check = 0;
1022    struct ExtraParams mExtraParams;
1023    if (AudioSetExtraParams(keyValueList, &count, &mExtraParams, &check) < 0) {
1024        return AUDIO_ERR_INTERNAL;
1025    }
1026    if (count != 0 && check == count) {
1027        SetValue(mExtraParams, render);
1028        return AUDIO_SUCCESS;
1029    } else {
1030        return AUDIO_ERR_INTERNAL;
1031    }
1032}
1033
1034int32_t AudioRenderGetExtraParams(struct IAudioRender *handle, char *keyValueList, uint32_t listLenth)
1035{
1036    AUDIO_FUNC_LOGD("Enter.");
1037    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1038    if (render == NULL || keyValueList == NULL || listLenth == 0) {
1039        return AUDIO_ERR_INVALID_PARAM;
1040    }
1041
1042    int32_t bufferSize = strlen(ROUTE_SAMPLE) + strlen(FORMAT_SAMPLE) + strlen(CHANNELS_SAMPLE) +
1043        strlen(FRAME_COUNT_SAMPLE) + strlen(SAMPLING_RATE_SAMPLE) + 1;
1044    if (listLenth < (uint32_t)bufferSize) {
1045        return AUDIO_ERR_INTERNAL;
1046    }
1047
1048    int32_t ret = AddElementToList(
1049        keyValueList, listLenth, AUDIO_ATTR_PARAM_ROUTE, &render->renderParam.renderMode.hwInfo.pathroute);
1050    if (ret < 0) {
1051        return AUDIO_ERR_INTERNAL;
1052    }
1053
1054    ret = AddElementToList(
1055        keyValueList, listLenth, AUDIO_ATTR_PARAM_FORMAT, &render->renderParam.frameRenderMode.attrs.format);
1056    if (ret < 0) {
1057        return AUDIO_ERR_INTERNAL;
1058    }
1059
1060    ret = AddElementToList(
1061        keyValueList, listLenth, AUDIO_ATTR_PARAM_CHANNELS, &render->renderParam.frameRenderMode.attrs.channelCount);
1062    if (ret < 0) {
1063        return AUDIO_ERR_INTERNAL;
1064    }
1065
1066    ret = AddElementToList(
1067        keyValueList, listLenth, AUDIO_ATTR_PARAM_FRAME_COUNT, &render->renderParam.frameRenderMode.frames);
1068    if (ret < 0) {
1069        return AUDIO_ERR_INTERNAL;
1070    }
1071
1072    ret = AddElementToList(
1073        keyValueList, listLenth, AUDIO_ATTR_PARAM_SAMPLING_RATE, &render->renderParam.frameRenderMode.attrs.sampleRate);
1074    if (ret < 0) {
1075        return AUDIO_ERR_INTERNAL;
1076    }
1077    return AUDIO_SUCCESS;
1078}
1079
1080int32_t AudioRenderReqMmapBuffer(
1081    struct IAudioRender *handle, int32_t reqSize, struct AudioMmapBufferDescriptor *desc)
1082{
1083    (void)handle;
1084    (void)reqSize;
1085    (void)desc;
1086    return AUDIO_SUCCESS;
1087}
1088
1089int32_t AudioRenderGetMmapPosition(struct IAudioRender *handle, uint64_t *frames, struct AudioTimeStamp *time)
1090{
1091    AUDIO_FUNC_LOGD("Enter.");
1092    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1093    if (render == NULL || frames == NULL || time == NULL) {
1094        return AUDIO_ERR_INVALID_PARAM;
1095    }
1096
1097    InterfaceLibModeRenderPassthrough *pInterfaceLibModeRender = AudioPassthroughGetInterfaceLibModeRender();
1098    if (pInterfaceLibModeRender == NULL || *pInterfaceLibModeRender == NULL) {
1099        AUDIO_FUNC_LOGE("pInterfaceLibModeRender Is NULL");
1100        return AUDIO_ERR_INTERNAL;
1101    }
1102    if (render->devDataHandle == NULL) {
1103        return AUDIO_ERR_INTERNAL;
1104    }
1105
1106    int32_t ret =
1107        (*pInterfaceLibModeRender)(render->devDataHandle, &render->renderParam, AUDIO_DRV_PCM_IOCTL_MMAP_POSITION);
1108    if (ret < 0) {
1109        AUDIO_FUNC_LOGE("Get Position FAIL!");
1110        return AUDIO_ERR_INTERNAL;
1111    }
1112
1113    *frames = render->renderParam.frameRenderMode.frames;
1114
1115    render->renderParam.frameRenderMode.time.tvSec =
1116        (int64_t)(render->renderParam.frameRenderMode.frames / render->renderParam.frameRenderMode.attrs.sampleRate);
1117
1118    uint64_t lastBufFrames =
1119        render->renderParam.frameRenderMode.frames % render->renderParam.frameRenderMode.attrs.sampleRate;
1120
1121    render->renderParam.frameRenderMode.time.tvNSec =
1122        (int64_t)((lastBufFrames * SEC_TO_NSEC) / render->renderParam.frameRenderMode.attrs.sampleRate);
1123
1124    *time = render->renderParam.frameRenderMode.time;
1125    return AUDIO_SUCCESS;
1126}
1127
1128int32_t AudioRenderTurnStandbyMode(struct IAudioRender *handle)
1129{
1130    AUDIO_FUNC_LOGD("Enter.");
1131    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1132    if (render == NULL) {
1133        return AUDIO_ERR_INVALID_PARAM;
1134    }
1135
1136    render->renderParam.renderMode.ctlParam.turnStandbyStatus = AUDIO_TURN_STANDBY_NOW;
1137
1138    int32_t ret = AudioRenderStop((AudioHandle)render);
1139    if (ret < 0) {
1140        return AUDIO_ERR_INTERNAL;
1141    }
1142    return AUDIO_SUCCESS;
1143}
1144
1145int32_t AudioRenderAudioDevDump(struct IAudioRender *handle, int32_t range, int32_t fd)
1146{
1147    AUDIO_FUNC_LOGD("Enter.");
1148    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1149    if (render == NULL) {
1150        return AUDIO_ERR_INVALID_PARAM;
1151    }
1152
1153    dprintf(fd, "%s%d\n", "Number of errors: ", render->errorLog.totalErrors);
1154    if (range < RANGE_MIN - 1 || range > RANGE_MAX) {
1155        dprintf(fd, "%s\n", "Out of range, invalid output");
1156        return AUDIO_SUCCESS;
1157    }
1158
1159    uint32_t mSize = render->errorLog.iter;
1160    if (range < RANGE_MIN) {
1161        dprintf(fd, "%-5s  %-10s  %s\n", "count", "errorCode", "Time");
1162        for (uint32_t i = 0; i < mSize; i++) {
1163            dprintf(fd, FORMAT_TWO, render->errorLog.errorDump[i].count + 1, render->errorLog.errorDump[i].errorCode,
1164                render->errorLog.errorDump[i].currentTime);
1165        }
1166    } else {
1167        dprintf(fd, "%-5s  %-10s  %-20s  %-15s  %s\n", "count", "errorCode", "frames", "fail reason", "Time");
1168        for (uint32_t i = 0; i < mSize; i++) {
1169            dprintf(fd, FORMAT_ONE, render->errorLog.errorDump[i].count + 1, render->errorLog.errorDump[i].errorCode,
1170                render->errorLog.errorDump[i].frames, render->errorLog.errorDump[i].reason,
1171                render->errorLog.errorDump[i].currentTime);
1172        }
1173    }
1174    return AUDIO_SUCCESS;
1175}
1176int32_t CallbackProcessing(AudioHandle handle, enum AudioCallbackType callBackType)
1177{
1178    struct AudioHwRender *render = (struct AudioHwRender *)handle;
1179    if (render == NULL) {
1180        AUDIO_FUNC_LOGI("Unregistered callback.\n");
1181        return HDF_FAILURE;
1182    }
1183    if (render->renderParam.frameRenderMode.callback.RenderCallback == NULL) {
1184        return HDF_FAILURE;
1185    }
1186
1187    bool isCallBack = false;
1188    switch (callBackType) {
1189        case AUDIO_NONBLOCK_WRITE_COMPLETED:
1190        case AUDIO_DRAIN_COMPLETED:
1191        case AUDIO_FLUSH_COMPLETED:
1192        case AUDIO_RENDER_FULL:
1193        case AUDIO_ERROR_OCCUR:
1194            isCallBack = true;
1195            break;
1196        default:
1197            break;
1198    }
1199
1200    if (!isCallBack) {
1201        AUDIO_FUNC_LOGI("No callback processing is required.\n");
1202        return HDF_ERR_NOT_SUPPORT;
1203    }
1204
1205    render->renderParam.frameRenderMode.callback.RenderCallback(
1206        &render->renderParam.frameRenderMode.callback, callBackType, NULL, render->renderParam.frameRenderMode.cookie);
1207    return HDF_SUCCESS;
1208}
1209
1210int32_t AudioRenderRegCallback(struct IAudioRender *render, struct IAudioCallback *audioCallback, int8_t cookie)
1211{
1212    AUDIO_FUNC_LOGD("Enter.");
1213    if (audioCallback == NULL || audioCallback->RenderCallback == NULL) {
1214        return AUDIO_ERR_INVALID_PARAM;
1215    }
1216
1217    struct AudioHwRender *pRender = (struct AudioHwRender *)render;
1218    if (pRender == NULL) {
1219        return AUDIO_ERR_INVALID_PARAM;
1220    }
1221
1222    pRender->renderParam.frameRenderMode.callback.RenderCallback = audioCallback->RenderCallback;
1223    pRender->renderParam.frameRenderMode.cookie = (void *)(uintptr_t)cookie;
1224    pRender->renderParam.renderMode.hwInfo.callBackEnable = true;
1225    return AUDIO_SUCCESS;
1226}
1227
1228int32_t AudioRenderDrainBuffer(struct IAudioRender *render, enum AudioDrainNotifyType *type)
1229{
1230    AUDIO_FUNC_LOGD("Enter.");
1231    struct AudioHwRender *pRender = (struct AudioHwRender *)render;
1232    if (pRender == NULL || type == NULL) {
1233        return AUDIO_ERR_INVALID_PARAM;
1234    }
1235    return AUDIO_ERR_NOT_SUPPORT;
1236}
1237
1238void AudioRenderRelease(struct IAudioRender *instance)
1239{
1240    (void)instance;
1241}
1242