You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
7.5 KiB
336 lines
7.5 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. Technologies Co., Ltd. 2020-2020. All rights reserved.
|
|
* Description: audio hal direct output source file.
|
|
* Author: yinyingcai
|
|
* Create: 2020-05-11
|
|
* Notes: NA
|
|
* History: 2020-05-11 yinyingcai for CodingStyle
|
|
*/
|
|
#define LOG_TAG "audio_hal_hdo"
|
|
#define LOG_NDEBUG 0
|
|
|
|
#include <cutils/properties.h>
|
|
#include <securec.h>
|
|
|
|
#include "audio_hw.h"
|
|
#include "vnaudio_dbg.h"
|
|
#include "audio_out_avplay.h"
|
|
#include "hdo.h"
|
|
#ifdef TV_TYPE
|
|
#include "aiao_wrap.h"
|
|
#endif
|
|
|
|
int hdo_init(struct audio_device* adev)
|
|
{
|
|
int ret;
|
|
trace();
|
|
|
|
ret = hal_avplay_initAvplayer(adev);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_initAvplayer failed(0x%x)", ret);
|
|
adev->hdoSupport = false;
|
|
return ret;
|
|
}
|
|
|
|
ret = hal_avplay_initsnd();
|
|
if (ret != 0) {
|
|
ALOGE("hal_snd_init failed(0x%x)", ret);
|
|
adev->hdoSupport = false;
|
|
hal_avplay_deinitAvplayer();
|
|
}
|
|
|
|
int32_t s32Ret;
|
|
|
|
s32Ret = wraper_init_hal_sound();
|
|
if (s32Ret != 0) {
|
|
ALOGE("wraper_init_Sound failed(0x%x)", s32Ret);
|
|
return 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void hdo_deinit(void)
|
|
{
|
|
int ret;
|
|
trace();
|
|
|
|
ret = hal_avplay_deinitsnd();
|
|
if (ret != 0) {
|
|
ALOGE("hal_snd_deinit failed\n");
|
|
}
|
|
|
|
ret = hal_avplay_deinitAvplayer();
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_deinitAvplayer failed\n");
|
|
}
|
|
}
|
|
|
|
int hdo_create(struct hdo_data** pphdo)
|
|
{
|
|
int ret;
|
|
char value[PROPERTY_VALUE_MAX] = {0};
|
|
unsigned int bEnableSaveES;
|
|
unsigned int bEnableSavePTS;
|
|
trace();
|
|
|
|
struct hdo_data* hdo = (struct hdo_data *)malloc(sizeof(struct hdo_data));
|
|
if (hdo == NULL) {
|
|
ALOGE("%s: malloc failed", __func__);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
ret = memset_s(hdo, sizeof(struct hdo_data), 0, sizeof(struct hdo_data));
|
|
if (ret != 0) {
|
|
ALOGE("memset_s hdo failed(0x%x)", ret);
|
|
free(hdo);
|
|
return ret;
|
|
}
|
|
|
|
hdo->fd_es = NULL;
|
|
hdo->fd_pts = NULL;
|
|
hdo->hAvplay = NOT_INITED_HANDLE;
|
|
hdo->bSetVolumeSuccess = TRUE;
|
|
hdo->bTrackMuted = FALSE;
|
|
hdo->userSetVolume = 0;
|
|
hdo->s32IntegerGain = 0;
|
|
hdo->s32DecimalGain = 0;
|
|
*pphdo = hdo;
|
|
|
|
property_get(PROPERTY_FILE_ES, value, "false");
|
|
bEnableSaveES = (strncmp(value, "true", sizeof("true")) == 0) ? DEBUG_TRUE : DEBUG_FALSE;
|
|
property_get(PROPERTY_FILE_PTS, value, "false");
|
|
bEnableSavePTS = (strncmp(value, "true", sizeof("true")) == 0) ? DEBUG_TRUE : DEBUG_FALSE;
|
|
|
|
if (bEnableSaveES == TRUE) {
|
|
hdo->fd_es = fopen(ES_FILE, "ab");
|
|
if (hdo->fd_es == NULL) {
|
|
ALOGD("%s: %s can not be created!", __func__, ES_FILE);
|
|
}
|
|
}
|
|
|
|
if (bEnableSavePTS == TRUE) {
|
|
hdo->fd_pts = fopen(PTS_FILE, "ab");
|
|
if (hdo->fd_pts == NULL) {
|
|
ALOGD("%s: %s can not be created!", __func__, PTS_FILE);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int hdo_open(struct hdo_data *hdo)
|
|
{
|
|
int ret;
|
|
|
|
ret = hal_avplay_create(hdo);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t hdo_get_buffer_size(const struct hdo_data* hdo)
|
|
{
|
|
size_t buffersize;
|
|
size_t chan_samp_sz;
|
|
audio_format_t format = hdo->out->format;
|
|
|
|
trace();
|
|
|
|
if (audio_has_proportional_frames(format)) {
|
|
chan_samp_sz = audio_bytes_per_sample(format);
|
|
chan_samp_sz *= hdo->out->config.channels;
|
|
} else {
|
|
chan_samp_sz = sizeof(int8_t);
|
|
}
|
|
|
|
buffersize = hdo->out->config.period_size * chan_samp_sz;
|
|
|
|
ALOGD("%s: buffersize=%d period_size:%d",
|
|
__func__, buffersize, hdo->out->config.period_size);
|
|
|
|
return buffersize;
|
|
}
|
|
|
|
uint32_t hdo_get_latency(const struct hdo_data *hdo)
|
|
{
|
|
uint32_t latency = (hdo->out->config.period_count * hdo->out->config.period_size * SECOND_TO_MS) /
|
|
(hdo->out->config.rate);
|
|
|
|
ALOGD("%s: latency=%d", __func__, latency);
|
|
|
|
return latency;
|
|
}
|
|
|
|
ssize_t hdo_write(struct hdo_data *hdo, const uint8_t* buffer, size_t bytes)
|
|
{
|
|
int ret;
|
|
trace();
|
|
ret = hal_avplay_write(hdo, buffer, bytes);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_write failed(0x%x)", ret);
|
|
}
|
|
/* always success, because can not do anythings when failed */
|
|
return 0;
|
|
}
|
|
|
|
int hdo_pause(struct hdo_data *hdo)
|
|
{
|
|
int ret;
|
|
trace();
|
|
|
|
if (hdo == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
ret = hal_avplay_pause(hdo);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_pause failed(0x%x)", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int hdo_resume(struct hdo_data *hdo)
|
|
{
|
|
int ret;
|
|
trace();
|
|
if (hdo == NULL) {
|
|
return -1;
|
|
}
|
|
ret = hal_avplay_resume(hdo);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_resume failed(0x%x)", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int hdo_flush(struct hdo_data *hdo)
|
|
{
|
|
int ret;
|
|
trace();
|
|
|
|
if (hdo == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
ret = hal_avplay_flush(hdo);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_flush failed(0x%x)", ret);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
int hdo_drain(const struct hdo_data *hdo __unused, int type __unused)
|
|
{
|
|
trace();
|
|
return 0;
|
|
}
|
|
|
|
int hdo_get_tstamp(const struct hdo_data *hdo, uint64_t *dsp_frames)
|
|
{
|
|
int ret = TD_FAILURE;
|
|
|
|
if ((hdo == NULL) || (dsp_frames == NULL)) {
|
|
return ret;
|
|
}
|
|
|
|
*dsp_frames = 0;
|
|
|
|
ret = hal_avplay_getstamp(hdo, hdo->out->sample_rate, dsp_frames);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_getstamp failed(0x%x)", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int hdo_close(struct hdo_data *hdo)
|
|
{
|
|
int ret = -1;
|
|
|
|
if (hdo == NULL) {
|
|
return ret;
|
|
}
|
|
|
|
ALOGD("hdo_close_audiochan PASSTHRU\n");
|
|
ret = hal_avplay_destoryaudio(hdo);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_destoryaudio failed(0x%x)", ret);
|
|
}
|
|
|
|
if (hdo->usecase == USECASE_AUDIO_PLAYBACK_DIRECT_NONTUNNEL) {
|
|
if (hdo->hAvplay != (uint32_t)(NOT_INITED_HANDLE)) {
|
|
(void)hal_avplay_destory(hdo);
|
|
}
|
|
} else {
|
|
if (hdo->usecase != USECASE_AUDIO_PLAYBACK_DIRECT_TUNNEL) {
|
|
ALOGE("%s:invalid usecase\n", __func__);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void hdo_destroy(struct hdo_data* hdo)
|
|
{
|
|
ALOGD("in function %s", __func__);
|
|
|
|
if (hdo == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (hdo->fd_es != NULL) {
|
|
fclose(hdo->fd_es);
|
|
hdo->fd_es = NULL;
|
|
}
|
|
if (hdo->fd_pts != NULL) {
|
|
fclose(hdo->fd_pts);
|
|
hdo->fd_pts = NULL;
|
|
}
|
|
free(hdo);
|
|
}
|
|
|
|
int hdo_create_hwsync_source(const int *sync_source)
|
|
{
|
|
int ret = hal_avplay_create_ext(sync_source);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_create_ext failed\n");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int hdo_destroy_hwsync_source(int sync_source)
|
|
{
|
|
int ret = hal_avplay_destroy_ext(sync_source);
|
|
if (ret != 0) {
|
|
ALOGE("hal_avplay_destroy_ext failed\n");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int hdo_obtain_hwsync_streaminfo(struct audio_device* adev)
|
|
{
|
|
int s32Ret;
|
|
|
|
trace();
|
|
|
|
if (adev == NULL) {
|
|
ALOGE("hdo null point");
|
|
return TD_FAILURE;
|
|
}
|
|
if (adev->hw_sync_id == NOT_INITED_HANDLE) {
|
|
ALOGE("HWAVSync avplay not created");
|
|
adev->stream_type = STREAM_NONE;
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
s32Ret = hal_avplay_getstreaminfo(adev);
|
|
if (s32Ret != TD_SUCCESS) {
|
|
ALOGE("getstreaminfo failed(0x%x)", s32Ret);
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|