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.

787 lines
29 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
* Description: video/audio interface.
* Author: Hisilicon
* Create: 2019-11-01
*/
#include "adp_uapi_ext.h"
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "securec.h"
#include "uapi_avplay.h"
#include "uapi_sound.h"
#include "uapi_ai.h"
#include "uapi_acodec.h"
#include "ha_codec.h"
#include "ha_codec_g711.h"
#include "ha_codec_mp3dec.h"
#include "ha_codec_mp2dec.h"
#include "ha_codec_aacdec.h"
#include "ha_codec_pcmdec.h"
#include "ha_codec_amrnb.h"
#include "ha_codec_amrwb.h"
#include "ha_codec_dolbytruehddec.h"
#include "ha_codec_dtshddec.h"
#if defined (DOLBYPLUS_HACODEC_SUPPORT)
#include "ha_codec_dolbyplusdec.h"
#endif
#include "ha_codec_passthrough.h"
#include "ha_codec_aacenc.h"
#include "ha_codec_dolbyms12dec.h"
#include "ha_codec_voice.h"
#include "ha_codec_opus.h"
#include "ha_codec_vorbis.h"
#include "ha_codec_dtsm6dec.h"
#include "ha_codec_dradec.h"
#ifdef ANDROID
#include <utils/Log.h>
#endif
#include "adp_common_ext.h"
#include "uapi_system.h"
#define ADP_DEMUX_NUM 5
#define ADP_DEMUX_PLAY 0
#define ADP_DEMUX_REC_0 1
#define ADP_DEMUX_REC_1 2
#define ADP_DEMUX_TIMESHIFT 3
#define ADP_DEMUX_PLAYBACK 4
#define ADP_UHD_WIDTH 3840
#define ADP_UHD_HEIGHT 2160
#define ADP_FHD_WIDTH 1920
#define ADP_FHD_HEIGHT 1080
#define ADP_HD_WIDTH 1280
#define ADP_HD_HEIGHT 720
/*
* big-endian pcm output format, if extword is 1, choose normal pcm decoder,
* if extword is 2, choose wifidsp_lpcm decoder(Frame Header:0xA0,0x06)
* if others, fail to decode.
*/
#define NORMAL_PCM_EXTWORD 1
#define WIFIDSP_LPCM_EXTWORD 2
#define DEC_OPEN_BUF_LEN 1024
#define MAX_ADEC_OPEN_CONFIG_LEN 1024
td_u8 g_dec_open_buf[DEC_OPEN_BUF_LEN];
static td_u8 g_adec_open_config[MAX_ADEC_OPEN_CONFIG_LEN] = {0};
#if defined (DOLBYPLUS_HACODEC_SUPPORT)
static ha_codec_dolbyplus_stream_info g_ddp_stream_info = {0};
/* dolby Dual Mono type control */
#endif
#ifdef ANDROID
#define LOG_MAX_LEN 1024
void log_print(const char *format, ...)
{
char log_str[LOG_MAX_LEN];
va_list args;
td_s32 ret;
va_start(args, format);
ret = vsnprintf_s(log_str, LOG_MAX_LEN, LOG_MAX_LEN - 1, format, args);
va_end(args);
if (ret < 0) {
printf("call vsnprintf_s failed.\n");
return;
}
android_printLog(ANDROID_LOG_ERROR, "SAMPLE", "%s", log_str);
}
#endif
__attribute__ ((constructor)) static void stdin_constructor(void)
{
td_s32 flags = fcntl(STDIN_FILENO, F_GETFL, 0);
if (flags < 0) {
printf("[%s:%d][ERROR] get flags failed.\n", __FUNCTION__, __LINE__);
} else if (((td_u32)flags & O_NONBLOCK) != 0) {
flags = (td_u32)flags & (~O_NONBLOCK);
flags = fcntl(STDIN_FILENO, F_SETFL, flags);
if (flags < 0) {
printf("[%s:%d][ERROR] set flags failed.\n", __FUNCTION__, __LINE__);
}
}
}
typedef struct {
uapi_acodec_channel uapi_channel;
ha_codec_channel mpi_channel;
} tran_channel;
static tran_channel g_tran_channel[] = {
{UAPI_ACODEC_CHANNEL_NONE, HA_CODEC_CHANNEL_NONE},
{UAPI_ACODEC_CHANNEL_LF, HA_CODEC_CHANNEL_LF},
{UAPI_ACODEC_CHANNEL_RF, HA_CODEC_CHANNEL_RF},
{UAPI_ACODEC_CHANNEL_CF, HA_CODEC_CHANNEL_CF},
{UAPI_ACODEC_CHANNEL_LS, HA_CODEC_CHANNEL_LS},
{UAPI_ACODEC_CHANNEL_RS, HA_CODEC_CHANNEL_RS},
{UAPI_ACODEC_CHANNEL_LFE, HA_CODEC_CHANNEL_LFE},
{UAPI_ACODEC_CHANNEL_CS, HA_CODEC_CHANNEL_CS},
{UAPI_ACODEC_CHANNEL_LR, HA_CODEC_CHANNEL_LR},
{UAPI_ACODEC_CHANNEL_RR, HA_CODEC_CHANNEL_RR},
{UAPI_ACODEC_CHANNEL_MAX, HA_CODEC_CHANNEL_MAX},
};
static ha_codec_channel track_channel_uapi_to_mpi(const uapi_acodec_channel uapi_in)
{
td_u32 i;
for (i = 0; i < sizeof(g_tran_channel) / sizeof(g_tran_channel[0]); i++) {
if (uapi_in == g_tran_channel[i].uapi_channel) {
return g_tran_channel[i].mpi_channel;
}
}
return HA_CODEC_CHANNEL_MAX;
}
static uapi_acodec_channel track_channel_mpi_to_uapi(const ha_codec_channel mpi_in)
{
td_u32 i;
for (i = 0; i < sizeof(g_tran_channel) / sizeof(g_tran_channel[0]); i++) {
if (mpi_in == g_tran_channel[i].mpi_channel) {
return g_tran_channel[i].uapi_channel;
}
}
return UAPI_ACODEC_CHANNEL_MAX;
}
td_s32 trans_dec_param_mpi_to_uapi(uapi_acodec_dec_param *uapi_param, const ha_codec_dec_param *param)
{
td_u32 i;
if (uapi_param == TD_NULL || param == TD_NULL) {
return TD_FAILURE;
}
uapi_param->private_data = param->private_data;
uapi_param->private_data_size = param->private_data_size;
uapi_param->pcm_attr.desired_out_channels = param->pcm_attr.desired_out_channels;
uapi_param->pcm_attr.interleaved = param->pcm_attr.interleaved;
uapi_param->pcm_attr.bit_per_sample = param->pcm_attr.bit_per_sample;
uapi_param->pcm_attr.desired_sample_rate = param->pcm_attr.desired_sample_rate;
for (i = 0; i < HA_CODEC_MAX_CHANNEL; i++) {
uapi_param->pcm_attr.channel_map[i] = track_channel_mpi_to_uapi(param->pcm_attr.channel_map[i]);
}
switch (param->dec_mode) {
case HA_CODEC_DEC_MODE_RAWPCM:
uapi_param->dec_mode = UAPI_ACODEC_DEC_MODE_RAWPCM;
break;
case HA_CODEC_DEC_MODE_THRU:
uapi_param->dec_mode = UAPI_ACODEC_DEC_MODE_THRU;
break;
case HA_CODEC_DEC_MODE_SIMUL:
uapi_param->dec_mode = UAPI_ACODEC_DEC_MODE_SIMUL;
break;
default:
uapi_param->dec_mode = UAPI_ACODEC_DEC_MODE_MAX;
break;
}
return TD_SUCCESS;
}
td_s32 trans_dec_param_uapi_to_mpi(const uapi_acodec_dec_param *uapi_param, ha_codec_dec_param *param)
{
td_u32 i;
if (uapi_param == TD_NULL || param == TD_NULL) {
return TD_FAILURE;
}
param->private_data = uapi_param->private_data;
param->private_data_size = uapi_param->private_data_size;
param->pcm_attr.desired_out_channels = uapi_param->pcm_attr.desired_out_channels;
param->pcm_attr.interleaved = uapi_param->pcm_attr.interleaved;
param->pcm_attr.bit_per_sample = uapi_param->pcm_attr.bit_per_sample;
param->pcm_attr.desired_sample_rate = uapi_param->pcm_attr.desired_sample_rate;
for (i = 0; i < HA_CODEC_MAX_CHANNEL; i++) {
param->pcm_attr.channel_map[i] = track_channel_uapi_to_mpi(uapi_param->pcm_attr.channel_map[i]);
}
switch (uapi_param->dec_mode) {
case UAPI_ACODEC_DEC_MODE_RAWPCM:
param->dec_mode = HA_CODEC_DEC_MODE_RAWPCM;
break;
case UAPI_ACODEC_DEC_MODE_THRU:
param->dec_mode = HA_CODEC_DEC_MODE_THRU;
break;
case UAPI_ACODEC_DEC_MODE_SIMUL:
param->dec_mode = HA_CODEC_DEC_MODE_SIMUL;
break;
default:
param->dec_mode = HA_CODEC_DEC_MODE_MAX;
break;
}
return TD_SUCCESS;
}
td_s32 trans_enc_param_mpi_to_uapi(uapi_acodec_enc_param *uapi_param, const ha_codec_enc_param *param)
{
if (uapi_param == TD_NULL || param == TD_NULL) {
return TD_FAILURE;
}
uapi_param->desired_out_channels = param->desired_out_channels;
uapi_param->interleaved = param->interleaved;
uapi_param->bit_per_sample = param->bit_per_sample;
uapi_param->desired_sample_rate = param->desired_sample_rate;
uapi_param->sample_per_frame = param->sample_per_frame;
uapi_param->private_data = param->private_data;
uapi_param->private_data_size = param->private_data_size;
return TD_SUCCESS;
}
td_s32 trans_enc_param_uapi_to_mpi(const uapi_acodec_enc_param *uapi_param, ha_codec_enc_param *param)
{
if (uapi_param == TD_NULL || param == TD_NULL) {
return TD_FAILURE;
}
param->desired_out_channels = uapi_param->desired_out_channels;
param->interleaved = uapi_param->interleaved;
param->bit_per_sample = uapi_param->bit_per_sample;
param->desired_sample_rate = uapi_param->desired_sample_rate;
param->sample_per_frame = uapi_param->sample_per_frame;
param->private_data = uapi_param->private_data;
param->private_data_size = uapi_param->private_data_size;
return TD_SUCCESS;
}
td_s32 adp_uapi_snd_init(td_void)
{
td_s32 ret;
uapi_snd_attr attr;
ret = uapi_snd_init();
if (ret != TD_SUCCESS) {
SAMPLE_COMMON_PRINTF("call uapi_snd_init failed.\n");
return ret;
}
ret = uapi_snd_get_default_open_attr(UAPI_SND_0, &attr);
if (ret != TD_SUCCESS) {
SAMPLE_COMMON_PRINTF("call uapi_snd_get_default_open_attr failed.\n");
return ret;
}
ret = uapi_snd_open(UAPI_SND_0, &attr);
if (ret != TD_SUCCESS) {
SAMPLE_COMMON_PRINTF("call uapi_snd_open failed.\n");
return ret;
}
return TD_SUCCESS;
}
td_s32 adp_uapi_snd_deinit(td_void)
{
td_s32 ret;
ret = uapi_snd_close(UAPI_SND_0);
if (ret != TD_SUCCESS) {
SAMPLE_COMMON_PRINTF("call uapi_snd_close failed.\n");
return ret;
}
ret = uapi_snd_deinit();
if (ret != TD_SUCCESS) {
SAMPLE_COMMON_PRINTF("call uapi_snd_deinit failed.\n");
return ret;
}
return TD_SUCCESS;
}
#define sample_common_dofunc_no_return(func) do { \
td_s32 ret_val_; \
ret_val_ = (func); \
if (ret_val_ != TD_SUCCESS) { \
SAMPLE_COMMON_PRINTF("\n\n!!! some audio codec NOT found. you may NOT able to decode some audio type.\n\n");; \
} \
} while (0)
static td_s32 adp_avplay_reg_adec_lib(td_void)
{
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.AMRWB.codec.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.MP3.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.MP2.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.AAC.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.DOLBYTRUEHD.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.AMRNB.codec.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.COOK.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.VOICE.codec.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.G711.codec.so"));
#ifdef DOLBYPLUS_HACODEC_SUPPORT
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.DOLBYPLUS.decode.so"));
#endif
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.DTSHD.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.DTSM6.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.PASSTHROUGH.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.PCM.decode.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.OPUS.codec.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.VORBIS.codec.so"));
sample_common_dofunc_no_return(uapi_avplay_register_acodec_lib("libHA.AUDIO.AVS3.decode.so"));
return TD_SUCCESS;
}
td_s32 adp_uapi_avplay_init(td_void)
{
(td_void)adp_avplay_reg_adec_lib();
return uapi_avplay_init();
}
#if defined (DOLBYPLUS_HACODEC_SUPPORT)
static td_void dd_plus_call_back(ha_codec_dolbyplus_event event, td_void *app_data)
{
ha_codec_dolbyplus_stream_info *info = (ha_codec_dolbyplus_stream_info *)app_data;
td_u32 dolby_acmod = 0;
td_bool draw_chn_bar = TD_TRUE;
dolby_acmod = (td_u32)(info->acmod);
if (event == EXT_DOLBYPLUS_EVENT_SOURCE_CHANGE) {
draw_chn_bar = TD_TRUE;
}
printf("dolby_acmod(%u) draw_chn_bar(%d)\n", dolby_acmod, draw_chn_bar);
return;
}
#endif
static td_s32 set_pcm_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is PCM\n");
td_bool is_big_endian = TD_FALSE;
ha_codec_wav_format wav_format = {0};
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
if (is_big_endian == TD_TRUE) {
wav_format.cb_size = 4; /* 4: Size of the extension */
wav_format.cb_ext_word[0] = NORMAL_PCM_EXTWORD;
}
if (wav_format.cb_ext_word[0] == NORMAL_PCM_EXTWORD || is_big_endian == TD_FALSE) {
wav_format.channels = 1;
wav_format.samples_per_sec = 48000; /* 48000: Sampling rate */
wav_format.bits_per_sample = 16; /* 16: Bits per sample */
}
ha_codec_pcm_dec_get_default_open_param(&param, &wav_format);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_mp2_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is MP2\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_mp2_dec_get_default_open_param(&param);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_aac_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is AAC\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_aac_dec_get_default_open_param(&param);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_mp3_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is MP3\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_mp3_dec_get_default_open_param(&param);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_amrnb_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is AMRNB\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_amrnb_decode_open_config *config =
(ha_codec_amrnb_decode_open_config*)g_adec_open_config;
ha_amrnb_get_dec_default_open_param(&param, config);
config->format = HA_CODEC_AMRNB_MIME;
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_amrwb_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is AMRWB\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_amrwb_decode_open_config *config =
(ha_codec_amrwb_decode_open_config*)g_adec_open_config;
ha_codec_amrwb_get_dec_default_open_param(&param, config);
config->format = HA_CODEC_AMRWB_FORMAT_MIME;
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_g711_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is G711\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_VOICE;
ha_codec_voice_open_config *config =
(ha_codec_voice_open_config*)g_adec_open_config;
config->voice_format = HA_CODEC_VOICE_G711_A;
config->sample_per_frame = 320; /* 320: Bytes per frame */
ha_codec_voice_get_dec_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_g726_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is G726\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_VOICE;
ha_codec_voice_open_config *config =
(ha_codec_voice_open_config*)g_adec_open_config;
config->voice_format = HA_CODEC_VOICE_G726_40KBPS;
config->sample_per_frame = 320; /* 320: Bytes per frame */
ha_codec_voice_get_dec_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_adpcm_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is ADPCM\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_VOICE;
ha_codec_voice_open_config *config =
(ha_codec_voice_open_config*)g_adec_open_config;
config->voice_format = HA_CODEC_VOICE_ADPCM_DVI4;
config->sample_per_frame = 320; /* 320: Bytes per frame */
ha_codec_voice_get_dec_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_ac3passthrough_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is AC3_PASSTHROUGH\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_PASSTHROUGH;
ha_codec_passthrough_decode_open_config *config = (ha_codec_passthrough_decode_open_config *)g_adec_open_config;
config->codec_id = HA_CODEC_ID_AC3PASSTHROUGH;
ha_codec_passthrough_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adec_attr->param.dec_mode = UAPI_ACODEC_DEC_MODE_THRU;
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_dtspassthrough_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is DTSPASSTHROUGH\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_PASSTHROUGH;
ha_codec_passthrough_decode_open_config *config = (ha_codec_passthrough_decode_open_config *)g_adec_open_config;
config->codec_id = HA_CODEC_ID_DTSPASSTHROUGH;
ha_codec_passthrough_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adec_attr->param.dec_mode = UAPI_ACODEC_DEC_MODE_THRU;
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_truehd_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is TRUEHD\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
adec_attr->id = UAPI_ACODEC_ID_PASSTHROUGH;
ha_codec_passthrough_decode_open_config *config = (ha_codec_passthrough_decode_open_config *)g_adec_open_config;
config->codec_id = HA_CODEC_ID_TRUEHD;
ha_codec_passthrough_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adec_attr->param.dec_mode = UAPI_ACODEC_DEC_MODE_THRU;
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_dolby_truehd_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is DOLBY_TRUEHD\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_truehd_decode_open_config *config =
(ha_codec_truehd_decode_open_config*)g_adec_open_config;
ha_codec_dolby_truehd_dec_get_default_open_config(config);
ha_codec_dolby_truehd_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_dtshd_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is DTSHD\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dtshd_decode_open_config *config =
(ha_codec_dtshd_decode_open_config*)g_adec_open_config;
ha_codec_dtshd_dec_get_default_open_config(config);
ha_codec_dtshd_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adec_attr->param.dec_mode = UAPI_ACODEC_DEC_MODE_SIMUL;
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_dtsm6_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is DTSM6\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dtsm6_decode_open_config *config =
(ha_codec_dtsm6_decode_open_config*)g_adec_open_config;
ha_codec_dtsm6_dec_get_default_open_config(config);
ha_codec_dtsm6_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
#if defined (DOLBYPLUS_HACODEC_SUPPORT)
static td_s32 set_dolby_plus_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is DOLBY_PLUS\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dolbyplus_decode_openconfig *config =
(ha_codec_dolbyplus_decode_openconfig*)g_adec_open_config;
ha_codec_dolbyplus_dec_get_default_open_config(config);
config->pfn_evt_cb_func[EXT_DOLBYPLUS_EVENT_SOURCE_CHANGE] = dd_plus_call_back;
config->app_data[EXT_DOLBYPLUS_EVENT_SOURCE_CHANGE] = &g_ddp_stream_info;
config->drc_mode = DOLBYPLUS_DRC_RF; /* Dolby DVB Broadcast default settings */
config->dmx_mode = DOLBYPLUS_DMX_SRND; /* Dolby DVB Broadcast default settings */
ha_codec_dolbyplus_dec_get_default_open_param(&param, config);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adec_attr->param.dec_mode = UAPI_ACODEC_DEC_MODE_SIMUL;
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
#endif
static td_s32 set_ms12_ddp_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is MS12_DDP\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dolbyms12_open_config ms12_cfg = {0};
ha_codec_dolbyms12_get_default_open_config(&ms12_cfg);
ha_codec_dolbyms12_get_default_open_param(&param, &ms12_cfg);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_ms12_aac_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is MS12_AAC\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dolbyms12_open_config ms12_cfg = {0};
ha_codec_dolbyms12_get_default_open_config(&ms12_cfg);
ms12_cfg.input_type = MS12_HEAAC;
ha_codec_dolbyms12_get_default_open_param(&param, &ms12_cfg);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_vorbis_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is VORBIS\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_vorbis_dec_get_defalut_open_param(&param);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_opus_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is OPUS\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_opus_head_config opus_head_cfg = {0};
ha_codec_opus_dec_get_default_head_config(&opus_head_cfg);
opus_head_cfg.version = 1;
opus_head_cfg.chan = 6; /* 6: Number of channels */
opus_head_cfg.preskip = 312; /* 312: preskip value. */
opus_head_cfg.gain = 0;
opus_head_cfg.sample_rate = 48000; /* 48000: Sampling rate */
opus_head_cfg.nb_streams = 4; /* 4: number of streams */
opus_head_cfg.nb_coupled = 2; /* 2: number of coupled */
opus_head_cfg.channel_map = 1;
opus_head_cfg.stream_map[0] = 0; /* 0: stream map index. 0: stream map data. */
opus_head_cfg.stream_map[1] = 4; /* 1: stream map index. 4: stream map data. */
opus_head_cfg.stream_map[2] = 1; /* 2: stream map index. 1: stream map data. */
opus_head_cfg.stream_map[3] = 2; /* 3: stream map index. 2: stream map data. */
opus_head_cfg.stream_map[4] = 3; /* 4: stream map index. 3: stream map data. */
opus_head_cfg.stream_map[5] = 5; /* 5: stream map index. 5: stream map data. */
ha_codec_opus_dec_get_default_open_param(&param, &opus_head_cfg);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_dra_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
SAMPLE_COMMON_PRINTF("acodec id is MULTICH PCM\n");
ha_codec_dec_param param;
trans_dec_param_uapi_to_mpi(&(adec_attr->param), &param);
ha_codec_dra_dec_get_open_param_multich_pcm(&param);
trans_dec_param_mpi_to_uapi(&(adec_attr->param), &param);
adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr));
return TD_SUCCESS;
}
static td_s32 set_avs3_attr(td_handle avplay, uapi_audio_decode_attr *adec_attr)
{
td_s32 ret;
SAMPLE_COMMON_PRINTF("acodec id is AVS3\n");
if (adec_attr == TD_NULL) {
SAMPLE_COMMON_PRINTF("avplay == 0x%x\n", avplay);
return TD_FAILURE;
}
SAMPLE_COMMON_PRINTF("acodec id is 0x%x\n", adec_attr->id);
ret = uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr);
if (ret != TD_SUCCESS) {
printf("set_attr failed, ret:0x%x\n", ret);
}
return TD_SUCCESS;
}
typedef td_s32 (*set_adec_attr_fn) (td_handle avplay, uapi_audio_decode_attr *adec_attr);
typedef struct {
uapi_acodec_id acodec_id;
set_adec_attr_fn set_adec_attr;
} acodec_attr_map;
static acodec_attr_map g_acodec_attr_map[] = {
{UAPI_ACODEC_ID_PCM, set_pcm_attr},
{UAPI_ACODEC_ID_MP2, set_mp2_attr},
{UAPI_ACODEC_ID_AAC, set_aac_attr},
{UAPI_ACODEC_ID_MP3, set_mp3_attr},
{UAPI_ACODEC_ID_AMRNB, set_amrnb_attr},
{UAPI_ACODEC_ID_AMRWB, set_amrwb_attr},
{UAPI_ACODEC_ID_G711, set_g711_attr},
{UAPI_ACODEC_ID_G726, set_g726_attr},
{UAPI_ACODEC_ID_ADPCM, set_adpcm_attr},
{UAPI_ACODEC_ID_AC3PASSTHROUGH, set_ac3passthrough_attr},
{UAPI_ACODEC_ID_DTSPASSTHROUGH, set_dtspassthrough_attr},
{UAPI_ACODEC_ID_TRUEHD, set_truehd_attr},
{UAPI_ACODEC_ID_DOLBY_TRUEHD, set_dolby_truehd_attr},
{UAPI_ACODEC_ID_DTSHD, set_dtshd_attr},
{UAPI_ACODEC_ID_DTSM6, set_dtsm6_attr},
#if defined (DOLBYPLUS_HACODEC_SUPPORT)
{UAPI_ACODEC_ID_DOLBY_PLUS, set_dolby_plus_attr},
#endif
{UAPI_ACODEC_ID_MS12_DDP, set_ms12_ddp_attr},
{UAPI_ACODEC_ID_MS12_AAC, set_ms12_aac_attr},
{UAPI_ACODEC_ID_VORBIS, set_vorbis_attr},
{UAPI_ACODEC_ID_OPUS, set_opus_attr},
{UAPI_ACODEC_ID_AVS3, set_avs3_attr},
{UAPI_ACODEC_ID_DRA, set_dra_attr},
};
td_s32 adp_uapi_avplay_set_adec_attr(td_handle avplay, td_u32 acodec_id)
{
uapi_audio_decode_attr adec_attr = {0};
td_s32 map_size = (td_s32)(sizeof(g_acodec_attr_map) / sizeof(g_acodec_attr_map[0]));
adp_api_run_return(uapi_avplay_get_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, &adec_attr));
adec_attr.id = acodec_id;
for (int i = 0; i < map_size; i++) {
if (g_acodec_attr_map[i].acodec_id == acodec_id) {
return g_acodec_attr_map[i].set_adec_attr(avplay, &adec_attr);
}
}
return set_dra_attr(avplay, &adec_attr);
}