/* * 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 #include #include #include #include #include "securec.h" #include "uapi_avplay.h" #include "uapi_sound.h" #include "uapi_ai.h" #include "uapi_acodec.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 #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 */ td_u32 g_dolby_acmod = 0; td_bool g_draw_chn_bar = TD_TRUE; #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 void stdin_constructor(void) __attribute__ ((constructor)); 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 (flags & O_NONBLOCK) { flags &= ~O_NONBLOCK; flags = fcntl(STDIN_FILENO, F_SETFL, flags); if (flags < 0) { printf("[%s:%d][ERROR] set flags failed.\n", __FUNCTION__, __LINE__); } } } 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() { 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")); return TD_SUCCESS; } td_s32 adp_uapi_avplay_init() { (td_void)adp_avplay_reg_adec_lib(); return uapi_avplay_init(); } td_s32 adp_uapi_avplay_set_vdec_attr(td_handle avplay, uapi_vcodec_type type, uapi_vdec_work_mode mode) { td_s32 ret; uapi_vdec_attr vdec_attr; ret = uapi_avplay_get_attr(avplay, UAPI_AVPLAY_ATTR_ID_VDEC, &vdec_attr); if (ret != TD_SUCCESS) { SAMPLE_COMMON_PRINTF("uapi_avplay_get_attr failed:%#x\n", ret); return ret; } vdec_attr.type = type; vdec_attr.work_mode = mode; vdec_attr.error_cover = 100; /* 100: vdec error cover */ vdec_attr.priority = 3; /* 3: vdec priority */ ret = uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_VDEC, &vdec_attr); if (ret != TD_SUCCESS) { SAMPLE_COMMON_PRINTF("call uapi_avplay_set_attr failed.\n"); return ret; } return ret; } #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; g_dolby_acmod = (td_u32)(info->acmod); if (event == EXT_DOLBYPLUS_EVENT_SOURCE_CHANGE) { g_draw_chn_bar = TD_TRUE; } 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->param); ha_codec_mp2_dec_get_default_open_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 = (ha_codec_dec_param *)&(adec_attr->param); ha_codec_aac_dec_get_default_open_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 = (ha_codec_dec_param *)&(adec_attr->param); ha_codec_mp3_dec_get_default_open_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 = (ha_codec_dec_param *)&(adec_attr->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; 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 = (ha_codec_dec_param *)&(adec_attr->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; 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->param); ha_codec_vorbis_dec_get_defalut_open_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 = (ha_codec_dec_param *)&(adec_attr->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); 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 = (ha_codec_dec_param *)&(adec_attr->param); ha_codec_dra_dec_get_open_param_multich_pcm(param); adp_api_run_return(uapi_avplay_set_attr(avplay, UAPI_AVPLAY_ATTR_ID_ADEC, adec_attr)); 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_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); }