524 lines
19 KiB
C
524 lines
19 KiB
C
/*
|
|
* Copyright (C) 2021 Amlogic Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "audio_hw_hal_decoder"
|
|
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
#include <pthread.h>
|
|
|
|
#include "aml_audio_log.h"
|
|
#include "audio_hw.h"
|
|
#include "audio_hw_utils.h"
|
|
#include "audio_hwsync.h"
|
|
#include "aml_dec_api.h"
|
|
#include "aml_ddp_dec_api.h"
|
|
#include "aml_dtshd_dec_api.h"
|
|
#include "aml_dtsx_dec_api.h"
|
|
#include "audio_hw_resource_mgr.h"
|
|
#include "hdmirx_utils.h"
|
|
#include "aml_audio_output.h"
|
|
#include "aml_hw_mixer.h"
|
|
#include "audio_decoder.h"
|
|
|
|
static void ddp_decoder_config_prepare(struct audio_stream_out *stream, aml_dcv_config_t *ddp_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
struct aml_audio_device *adev = aml_out->dev;
|
|
|
|
adev->dcvlib_bypass_enable = 0;
|
|
ddp_config->digital_raw = AML_DEC_CONTROL_CONVERT;
|
|
|
|
if (aml_out->ad_substream_supported) {
|
|
ddp_config->decoding_mode = DDP_DECODE_MODE_AD_SUBSTREAM;
|
|
} else if (aml_out->dec_param.ad_mix_enable) {
|
|
ddp_config->decoding_mode = DDP_DECODE_MODE_AD_INDEPENDENT;
|
|
} else {
|
|
ddp_config->decoding_mode = DDP_DECODE_MODE_SINGLE;
|
|
}
|
|
|
|
if (aml_out->hal_internal_format == AUDIO_FORMAT_E_AC3) {
|
|
ddp_config->nIsEc3 = 1;
|
|
} else if (aml_out->hal_internal_format == AUDIO_FORMAT_AC3) {
|
|
ddp_config->nIsEc3 = 0;
|
|
}
|
|
ddp_config->is_pcmout_32bits = (adev->audio_process_bitwidth == 32);
|
|
|
|
AM_LOGI("digital_raw:%d, dual_output_flag:%d, IsEc3:%d, mode %d, %d. is_pcmout_32bits %d",
|
|
ddp_config->digital_raw, aml_out->dual_output_flag, ddp_config->nIsEc3, ddp_config->decoding_mode, aml_out->ad_substream_supported, ddp_config->is_pcmout_32bits);
|
|
}
|
|
|
|
static void dts_decoder_config_prepare(struct audio_stream_out *stream, aml_dec_config_t *dec_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
struct aml_audio_device *adev = aml_out->dev;
|
|
struct aml_arc_hdmi_desc *p_hdmi_descs = get_arc_hdmi_cap(adev);
|
|
int output_bitwidth = 16;
|
|
|
|
adev->dtslib_bypass_enable = 0;
|
|
|
|
{
|
|
int dts_out_ch;
|
|
bool non_spk = (adev->active_outport == OUTPORT_HEADPHONE) ||
|
|
(adev->active_outport == OUTPORT_A2DP) ||
|
|
(adev->active_outport == OUTPORT_HDMI_ARC);
|
|
bool vx_want_auto = adev->native_postprocess.libvx_exist && adev->effect_ctrl.vx_enable;
|
|
|
|
AM_LOGI("dts out-ch decide: outport=%s(%d) non_spk=%d libvx=%d vx_enable=%d dap_enable=%d "
|
|
"effect_mode=%d(1=OFF,2=DAP,3=VX,4=AUTO) virtualXlib1=%d vx_force_stereo=%d ms12_en=%d",
|
|
outputPort2Str(adev->active_outport), adev->active_outport, non_spk,
|
|
adev->native_postprocess.libvx_exist, adev->effect_ctrl.vx_enable,
|
|
adev->effect_ctrl.dap_enable, adev->effect_ctrl.effect_mode,
|
|
adev->effect_ctrl.virtualXlib1_state, adev->native_postprocess.vx_force_stereo,
|
|
(eDolbyMS12Lib == adev->dolby_lib_type && adev->ms12.dolby_ms12_enable));
|
|
|
|
if (non_spk) {
|
|
dts_out_ch = 2;
|
|
AM_LOGI("set dts output mode to stereo(2): reason=non-speaker outport");
|
|
} else if (vx_want_auto) {
|
|
dts_out_ch = 0;
|
|
AM_LOGI("set dts output mode to auto(0): reason=speaker + libvx && vx_enable");
|
|
} else {
|
|
dts_out_ch = 2;
|
|
AM_LOGI("set dts output mode to stereo(2): reason=speaker but libvx=%d vx_enable=%d",
|
|
adev->native_postprocess.libvx_exist, adev->effect_ctrl.vx_enable);
|
|
}
|
|
dca_set_out_ch_internal(dts_out_ch);
|
|
}
|
|
|
|
if (32 == adev->audio_process_bitwidth) {
|
|
output_bitwidth = 24; // DTS:X just support 16/24 bit pcm output.
|
|
} else {
|
|
output_bitwidth = 16;
|
|
}
|
|
|
|
if (adev->dts_lib_type == eDTSXLib) {
|
|
dec_config->dtsx_config.digital_raw = AML_DEC_CONTROL_CONVERT;
|
|
dec_config->dtsx_config.is_dtscd = aml_out->is_dtscd;
|
|
|
|
dec_config->dtsx_config.dev = (void *)adev;
|
|
dec_config->dtsx_config.stream = (void*)aml_out;
|
|
if (adev->hdmi_format == BYPASS) {
|
|
dec_config->dtsx_config.passthroug_enable = 1;
|
|
} else {
|
|
dec_config->dtsx_config.passthroug_enable = 0;
|
|
}
|
|
if ((adev->active_outport & OUTPORT_HDMI_ARC) != 0 || (adev->active_outport & AUDIO_DEVICE_OUT_HDMI) != 0) {
|
|
dec_config->dtsx_config.is_hdmi_output = 1;
|
|
} else {
|
|
dec_config->dtsx_config.is_hdmi_output = 0;
|
|
}
|
|
if (p_hdmi_descs->dtshd_fmt.is_support) {
|
|
dec_config->dtsx_config.sink_dev_type = p_hdmi_descs->dtshd_fmt.dts_vsdb_byte3;
|
|
} else {
|
|
dec_config->dtsx_config.sink_dev_type = 0; //CA(0),MA(1),P1(2),P2(4)
|
|
}
|
|
|
|
dec_config->dtsx_config.output_bw = output_bitwidth;
|
|
|
|
if (is_STB(adev)) {
|
|
dec_config->dtsx_config.device_type = STB;
|
|
if (p_hdmi_descs->pcm_fmt.max_channels == 8 && adev->hdmi_format == PCM) {
|
|
ALOGI("%s sink support multi-ch pcm, and dtsx decoder bus0 output multi-ch pcm when stream channel != 2", __func__);
|
|
dec_config->dtsx_config.sink_support_multich_pcm = true;
|
|
}
|
|
} else {
|
|
dec_config->dtsx_config.device_type = TV;
|
|
}
|
|
ALOGI("[%s:%d] digital_raw:%d dual_output:%d is_dtscd:%d bypass:%d hdmi_out:%d support_mch_pcm:%d output_bw:%d", __func__, __LINE__,
|
|
dec_config->dtsx_config.digital_raw, aml_out->dual_output_flag, dec_config->dtsx_config.is_dtscd,
|
|
dec_config->dtsx_config.passthroug_enable, dec_config->dtsx_config.is_hdmi_output,
|
|
dec_config->dtsx_config.sink_support_multich_pcm, dec_config->dtsx_config.output_bw);
|
|
|
|
} else if (adev->dts_lib_type == eDTSHDLib) {
|
|
dec_config->dca_config.digital_raw = AML_DEC_CONTROL_CONVERT;
|
|
|
|
dec_config->dca_config.dev = (void *)adev;
|
|
ALOGI("[%s:%d] digital_raw:%d, dual_output_flag:%d, is_dtscd:%d", __func__, __LINE__,
|
|
dec_config->dca_config.digital_raw, aml_out->dual_output_flag, dec_config->dca_config.is_dtscd);
|
|
} else {
|
|
ALOGE("[%s:%d] Without any dts library", __func__, __LINE__);
|
|
}
|
|
}
|
|
|
|
static void mad_decoder_config_prepare(struct audio_stream_out *stream, aml_mad_config_t *mad_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
mad_config->channel = aml_out->hal_ch;
|
|
mad_config->samplerate = aml_out->hal_rate;
|
|
mad_config->mpeg_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void faad_decoder_config_prepare(struct audio_stream_out *stream, aml_faad_config_t *faad_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
|
|
faad_config->channel = aml_out->hal_ch;
|
|
faad_config->samplerate = aml_out->hal_rate;
|
|
faad_config->aac_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void pcm_decoder_config_prepare(struct audio_stream_out *stream, aml_pcm_config_t *pcm_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
|
|
pcm_config->channel = aml_out->hal_ch;
|
|
pcm_config->samplerate = aml_out->hal_rate;
|
|
pcm_config->pcm_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void adpcm_decoder_config_prepare(struct audio_stream_out *stream, aml_adpcm_config_t *adpcm_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
adpcm_config->channel = aml_out->hal_ch;
|
|
adpcm_config->samplerate = aml_out->hal_rate;
|
|
adpcm_config->pcm_format = aml_out->hal_format;
|
|
adpcm_config->block_size = aml_out->dec_param.hal_decode_block_size;
|
|
}
|
|
|
|
static void flac_decoder_config_prepare(struct audio_stream_out *stream, aml_flac_config_t *flac_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
|
|
flac_config->channel = aml_out->hal_ch;
|
|
flac_config->samplerate = aml_out->hal_rate;
|
|
flac_config->flac_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void vorbis_decoder_config_prepare(struct audio_stream_out *stream, aml_vorbis_config_t *vorbis_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
|
|
vorbis_config->channel = aml_out->hal_ch;
|
|
vorbis_config->samplerate = aml_out->hal_rate;
|
|
vorbis_config->vorbis_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void opus_decoder_config_prepare(struct audio_stream_out *stream, aml_opus_config_t *opus_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
opus_config->channel = aml_out->hal_ch;
|
|
opus_config->samplerate = aml_out->hal_rate;
|
|
opus_config->opus_format = aml_out->hal_format;
|
|
}
|
|
|
|
static void mpegh_decoder_config_prepare(struct audio_stream_out *stream, aml_mpegh_config_t *mpegh_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
struct aml_audio_device *adev = aml_out->dev;
|
|
if (eDolbyMS12Lib == adev->dolby_lib_type) {
|
|
mpegh_config->channel = 6;
|
|
} else {
|
|
mpegh_config->channel = 2;
|
|
}
|
|
mpegh_config->samplerate = aml_out->hal_rate;
|
|
mpegh_config->mpegh_format = aml_out->hal_internal_format;
|
|
}
|
|
|
|
static int aml_decoder_config_prepare(struct audio_stream_out *stream, audio_format_t format, aml_dec_config_t *dec_config)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
struct aml_audio_device *adev = aml_out->dev;
|
|
|
|
if (eDolbyMS12Lib != adev->dolby_lib_type && aml_out->source_type == DTV_SRC) {
|
|
dec_config->dec_left_gain = dec_config->dec_right_gain = aml_out->dec_param.dec_gain;
|
|
dec_config->ad_mixing_enable = aml_out->dec_param.ad_mix_enable;
|
|
dec_config->mixer_level = aml_out->dec_param.mixing_level;
|
|
dec_config->advol_level = aml_out->dec_param.advol_level;
|
|
AM_LOGI("out %p, mixer_level %d ad_mixing_enable %d advol %d. dec gain %f", aml_out, dec_config->mixer_level, dec_config->ad_mixing_enable, dec_config->advol_level, dec_config->dec_left_gain);
|
|
} else {
|
|
dec_config->dec_left_gain = dec_config->dec_right_gain = 1.0;
|
|
}
|
|
|
|
#ifdef NO_SERVER
|
|
adev->decoder_drc_control = aml_audio_get_drc_control(&adev->alsa_mixer);
|
|
#endif
|
|
dec_config->drc_control = adev->decoder_drc_control;
|
|
dec_config->downmix_type = adev->downmix_type;
|
|
|
|
switch (format) {
|
|
case AUDIO_FORMAT_AC3:
|
|
case AUDIO_FORMAT_E_AC3: {
|
|
ddp_decoder_config_prepare(stream, &dec_config->dcv_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_DTS:
|
|
case AUDIO_FORMAT_DTS_HD: {
|
|
dts_decoder_config_prepare(stream, dec_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_PCM_16_BIT:
|
|
case AUDIO_FORMAT_PCM_32_BIT:
|
|
case AUDIO_FORMAT_PCM_8_BIT:
|
|
case AUDIO_FORMAT_PCM_8_24_BIT:
|
|
case AUDIO_FORMAT_PCM_LPCM_DVD:
|
|
case AUDIO_FORMAT_PCM_LPCM_1394:
|
|
case AUDIO_FORMAT_PCM_LPCM_BLURAY: {
|
|
pcm_decoder_config_prepare(stream, &dec_config->pcm_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_PCM_ADPCM_IMA_WAV: {
|
|
adpcm_decoder_config_prepare(stream, &dec_config->adpcm_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_MP3:
|
|
case AUDIO_FORMAT_MP2: {
|
|
mad_decoder_config_prepare(stream, &dec_config->mad_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_AAC:
|
|
case AUDIO_FORMAT_AAC_LATM:
|
|
case AUDIO_FORMAT_HE_AAC_V1:
|
|
case AUDIO_FORMAT_HE_AAC_V2:{
|
|
faad_decoder_config_prepare(stream, &dec_config->faad_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_FLAC: {
|
|
flac_decoder_config_prepare(stream, &dec_config->flac_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_OPUS: {
|
|
opus_decoder_config_prepare(stream, &dec_config->opus_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_VORBIS: {
|
|
vorbis_decoder_config_prepare(stream, &dec_config->vorbis_config);
|
|
break;
|
|
}
|
|
case AUDIO_FORMAT_MPEGH:
|
|
case AUDIO_FORMAT_MPEGH_BL_L3:
|
|
case AUDIO_FORMAT_MPEGH_BL_L4:
|
|
case AUDIO_FORMAT_MPEGH_LC_L3:
|
|
case AUDIO_FORMAT_MPEGH_LC_L4: {
|
|
mpegh_decoder_config_prepare(stream, &dec_config->mpegh_config);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int dca_get_out_ch_internal(void)
|
|
{
|
|
struct aml_audio_device *adev = (struct aml_audio_device *)adev_get_handle();
|
|
if (!adev)
|
|
return -1;
|
|
if (adev->dts_lib_type == eDTSXLib) {
|
|
return dtsx_get_out_ch_internal();
|
|
} else {
|
|
return dtshd_get_out_ch_internal();
|
|
}
|
|
}
|
|
|
|
uint32_t dca_get_out_chmask_internal(void)
|
|
{
|
|
struct aml_audio_device *adev = (struct aml_audio_device *)adev_get_handle();
|
|
if (!adev)
|
|
return -1;
|
|
if (adev->dts_lib_type == eDTSXLib) {
|
|
return dtsx_get_out_chmask_internal();
|
|
} else {
|
|
return dtshd_get_out_chmask_internal();
|
|
}
|
|
}
|
|
|
|
int dca_set_out_ch_internal(int ch_num)
|
|
{
|
|
struct aml_audio_device *adev = (struct aml_audio_device *)adev_get_handle();
|
|
if (!adev)
|
|
return -1;
|
|
AM_LOGI("dca_set_out_ch_internal ch=%d(%s) dts_lib=%d vx_enable=%d effect_mode=%d",
|
|
ch_num, (ch_num == 0) ? "auto" : (ch_num == 2) ? "stereo" : "other",
|
|
adev->dts_lib_type, adev->effect_ctrl.vx_enable, adev->effect_ctrl.effect_mode);
|
|
if (adev->dts_lib_type == eDTSXLib) {
|
|
return dtsx_set_out_ch_internal(ch_num);
|
|
} else {
|
|
return dtshd_set_out_ch_internal(ch_num);
|
|
}
|
|
}
|
|
|
|
int audio_decoder_release(struct audio_stream_out *stream)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
|
|
if (!aml_out || !aml_out->aml_dec) {
|
|
return 0;
|
|
}
|
|
aml_decoder_release(aml_out->aml_dec);
|
|
aml_out->aml_dec = NULL;
|
|
return 0;
|
|
}
|
|
|
|
int audio_decoder_init(struct audio_stream_out *stream)
|
|
{
|
|
struct aml_stream_out *aml_out = NULL;
|
|
struct aml_audio_device *adev = NULL;
|
|
int ret = -1;
|
|
|
|
if (!stream) {
|
|
AM_LOGE("invalid stream %p", stream);
|
|
return -1;
|
|
}
|
|
aml_out = (struct aml_stream_out *)stream;
|
|
adev = aml_out->dev;
|
|
memset(&aml_out->dec_config, 0, sizeof(aml_dec_config_t));
|
|
AM_LOGI("+<in>");
|
|
|
|
ret = aml_decoder_config_prepare(stream, aml_out->hal_internal_format, &aml_out->dec_config);
|
|
if (ret < 0) {
|
|
AM_LOGE("config decoder error");
|
|
return ret;
|
|
}
|
|
|
|
ret = aml_decoder_init(&aml_out->aml_dec, aml_out->hal_internal_format, (aml_dec_config_t *)&aml_out->dec_config);
|
|
if (ret < 0) {
|
|
AM_LOGE("aml_decoder_init failed");
|
|
return ret;
|
|
}
|
|
|
|
if (eDolbyMS12Lib != adev->dolby_lib_type) {
|
|
pthread_mutex_lock(&adev->lock);
|
|
/*coverity[missing_lock]:adev->hw_mixer.start_buf does not need to be lock*/
|
|
if (!adev->hw_mixer.start_buf) {
|
|
aml_hw_mixer_init(&adev->hw_mixer);
|
|
} else {
|
|
aml_hw_mixer_reset(&adev->hw_mixer);
|
|
}
|
|
pthread_mutex_unlock(&adev->lock);
|
|
}
|
|
|
|
AM_LOGI("-<out> init success! ret=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
int audio_decoder_reset(struct audio_stream_out *stream)
|
|
{
|
|
int ret = -1;
|
|
|
|
audio_decoder_release(stream);
|
|
aml_audio_spdif_output_close_all();
|
|
ret = audio_decoder_init(stream);
|
|
|
|
AM_LOGI("ret=%d", ret);
|
|
return ret;
|
|
}
|
|
|
|
int audio_decoder_process(struct audio_stream_out *stream,
|
|
struct audio_buffer *abuffer,
|
|
audio_decoder_frame_cb cb)
|
|
{
|
|
struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
|
|
struct aml_audio_device *adev = NULL;
|
|
aml_dec_t *aml_dec = NULL;
|
|
struct audio_buffer ainput;
|
|
int decoder_ret = 0;
|
|
int used_size = 0;
|
|
int left_bytes = 0;
|
|
bool try_again = false;
|
|
int cb_ret = 0;
|
|
|
|
if (!stream) {
|
|
AM_LOGE("invalid stream %p", stream);
|
|
return -1;
|
|
}
|
|
if (false == check_audio_buffer_valid(abuffer)) {
|
|
AM_LOGE("audio buffer checked fail");
|
|
return -1;
|
|
}
|
|
|
|
adev = aml_out->dev;
|
|
if (NULL == aml_out->aml_dec) {
|
|
decoder_ret = audio_decoder_init(stream);
|
|
if (decoder_ret < 0) {
|
|
AM_LOGE("audio_decoder_init fail");
|
|
return decoder_ret;
|
|
}
|
|
}
|
|
|
|
aml_dec = aml_out->aml_dec;
|
|
if (!aml_dec) {
|
|
return -1;
|
|
}
|
|
|
|
memcpy(&ainput, abuffer, sizeof(ainput));
|
|
if (!ainput.b_pts_valid ||
|
|
(ainput.pts == aml_dec->last_in_frame_pts) ||
|
|
(ainput.pts == NULL_INT64) ||
|
|
(ainput.pts == HWSYNC_PTS_NA)) {
|
|
AM_LOGI_IF(adev->debug_flag, "pts_valid:%d ainput.pts(0x%"PRIx64")->out_frame_pts(0x%"PRIx64")",
|
|
abuffer->b_pts_valid, ainput.pts, aml_dec->out_frame_pts);
|
|
ainput.pts = aml_dec->out_frame_pts;
|
|
ainput.b_pts_valid = false;
|
|
}
|
|
aml_dec->last_in_frame_pts = abuffer->pts;
|
|
|
|
left_bytes = ainput.size;
|
|
do {
|
|
try_again = false;
|
|
ainput.buffer = (const uint8_t *)ainput.buffer + used_size;
|
|
ainput.size = left_bytes;
|
|
used_size = 0;
|
|
|
|
AM_LOGI_IF(adev->debug_flag, "dec: %p, in pts:0x%"PRIx64" (%"PRIu64" ms) size: %"PRId32"",
|
|
aml_dec, ainput.pts, ainput.pts / 90, ainput.size);
|
|
|
|
if (cb) {
|
|
cb_ret = cb(stream, aml_dec, &ainput, AUDIO_DECODER_PRE);
|
|
if (cb_ret < 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
decoder_ret = aml_decoder_process(aml_dec, &ainput, &used_size);
|
|
if (decoder_ret == AML_DEC_RETURN_TYPE_CACHE_DATA) {
|
|
AM_LOGI_IF(adev->debug_flag, "cache the data to decode");
|
|
return abuffer->size;
|
|
} else if (decoder_ret == AML_DEC_RETURN_TYPE_FAIL) {
|
|
AM_LOGI_IF(adev->debug_flag, "aml_decoder_process error, ret:%d", decoder_ret);
|
|
break;
|
|
}
|
|
|
|
left_bytes -= used_size;
|
|
aml_out->consumedsize += used_size;
|
|
|
|
ainput.b_pts_valid = false;
|
|
aml_dec->out_frame_pts = ainput.pts;
|
|
|
|
AM_LOGI_IF(adev->debug_flag, "out pts:0x%"PRIx64" (%"PRIu64" ms) pcm len=%d raw len=%d used_size %d left_bytes=%d",
|
|
aml_dec->dec_pcm_data.pts, aml_dec->dec_pcm_data.pts / 90,
|
|
aml_dec->dec_pcm_data.data_len, aml_dec->dec_raw_data.data_len,
|
|
used_size, left_bytes);
|
|
|
|
if (cb) {
|
|
cb_ret = cb(stream, aml_dec, &ainput, decoder_ret);
|
|
if (cb_ret < 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((abuffer->format == AUDIO_FORMAT_DTS ||
|
|
abuffer->format == AUDIO_FORMAT_DTS_HD) &&
|
|
decoder_ret == AML_DEC_RETURN_TYPE_NEED_DEC_AGAIN) {
|
|
try_again = true;
|
|
}
|
|
} while (((left_bytes > 0) || aml_dec->fragment_left_size || try_again) && !aml_out->fast_quit);
|
|
|
|
return abuffer->size;
|
|
}
|