/* * Copyright (C) 2022 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 "aml_enc_api" #include "aml_audio_log.h" #include "aml_aac_enc_api.h" #include "aml_enc_api.h" #include "audio_hw_utils.h" static aml_enc_func_t * get_encoder_function(enc_encoding_format_t format) { switch (format) { case ENC_ENCODE_AAC: { return &enc_aac_func; } default: ALOGE("[%s:%d] doesn't support encoder format:%d", __func__, __LINE__, format); return NULL; } return NULL; } int aml_encoder_init(aml_enc_t **aml_enc, aml_enc_config_t *enc_config) { int ret = 0; aml_enc_func_t *enc_fun= NULL; enc_encoding_format_t format = enc_config->format; enc_fun = get_encoder_function(format); if (enc_fun == NULL) { ALOGE("[%s:%d] get enc_fun is null", __func__, __LINE__); return -1; } if (enc_fun->enc_init) { ret = enc_fun->enc_init(aml_enc, enc_config); if (ret < 0) { return ret; } (*aml_enc)->format = format; ALOGV("[%s:%d] finish, ret: %d, enc: %p", __func__, __LINE__, ret, *aml_enc); } else { return -1; } return ret; } int aml_encoder_process(aml_enc_t *aml_enc, int16_t* in_buffer, size_t bytes, unsigned char*out_buffer, int *out_length) { int ret = -1; aml_enc_func_t *enc_fun= NULL; if (aml_enc == NULL || in_buffer == NULL || out_buffer == NULL || out_length == NULL) { ALOGE("%s aml_enc (%p), in_buffer (%p), out_buffer (%p), out_len (%p)\n", __func__, aml_enc, in_buffer, out_buffer, out_length); return -1; } enc_fun = get_encoder_function(aml_enc->format); if (enc_fun == NULL) { ALOGW("[%s:%d] get enc_fun is null", __func__, __LINE__); return -1; } if (enc_fun->enc_process) { ret = enc_fun->enc_process(aml_enc, in_buffer, bytes, out_buffer, out_length); } else { ALOGE("[%s:%d] enc_process is null", __func__, __LINE__); return -1; } return ret; } int aml_encoder_capture(struct aml_enc_ctx *enc_ctx, const void *in_buf, int32_t in_size, void *out_abuffer) { int16_t *capture_tmp_buf = (int16_t *)in_buf; if (enc_ctx->enc_handle && in_buf && in_size) { int enc_ret = 0, out_size = 0; memset(enc_ctx->enc_data.pData, 0, sizeof(enc_ctx->enc_data.pData)); if ((enc_ret = aml_encoder_process(enc_ctx->enc_handle, capture_tmp_buf, in_size, enc_ctx->enc_data.pData, &out_size)) == 0 && (out_size > 0)) { enc_ctx->enc_data.dataLen = out_size; if (get_debug_value(AML_DUMP_AUDIOHAL_OUT)) { aml_dump_audio_bitstreams("hal_out.aac", enc_ctx->enc_data.pData, enc_ctx->enc_data.dataLen); } } } else { enc_ctx->enc_data.dataLen = 0; } enc_ctx->enc_data.pts = 0; if (out_abuffer && enc_ctx->enc_buf_space >= sizeof(enc_data_t)) memcpy(out_abuffer, &enc_ctx->enc_data, sizeof(enc_data_t)); return sizeof(enc_data_t); } int aml_encoder_getinfo(aml_enc_t *aml_enc, aml_enc_info_type_t info_type, aml_enc_info_t *enc_info) { int ret = -1; if (aml_enc == NULL || enc_info == NULL) { ALOGE("%s aml_enc is %p, enc_info is %p\n", __func__, aml_enc, enc_info); return -1; } aml_enc_func_t *enc_fun= NULL; enc_fun = get_encoder_function(aml_enc->format); if (enc_fun == NULL) { ALOGE("[%s:%d] get enc_fun is null", __func__, __LINE__); return -1; } if (enc_fun->enc_info) { ret = enc_fun->enc_info(aml_enc, info_type, enc_info); } else { ALOGE("[%s:%d] enc_info is null", __func__, __LINE__); return -1; } return ret; } int aml_encoder_release(aml_enc_t *aml_enc) { int ret = -1; aml_enc_func_t *enc_fun = NULL; if (aml_enc == NULL) { ALOGE("%s aml_enc is NULL\n", __func__); return -1; } enc_fun = get_encoder_function(aml_enc->format); if (enc_fun == NULL) { ALOGE("[%s:%d] get enc_fun is null", __func__, __LINE__); return -1; } if (enc_fun->enc_release) { ret = enc_fun->enc_release(aml_enc); ALOGV("[%s:%d] finish, ret: %d", __func__, __LINE__, ret); } else { ALOGE("[%s:%d] enc_release is null", __func__, __LINE__); return -1; } return ret; } int aml_encoder_config(aml_enc_t *aml_enc, aml_enc_config_type_t config_type, aml_enc_config_t * enc_config) { int ret = -1; aml_enc_func_t *enc_fun = NULL; if (aml_enc == NULL) { ALOGE("%s aml_enc is NULL\n", __func__); return -1; } enc_fun = get_encoder_function(aml_enc->format); if (enc_fun == NULL) { ALOGW("[%s:%d] get enc_fun is null", __func__, __LINE__); return -1; } if (enc_fun->enc_config) { ret = enc_fun->enc_config(aml_enc, config_type, enc_config); } else { ALOGE("[%s:%d] enc_config is null", __func__, __LINE__); return -1; } return ret; } static int aac_encode_config_prepare(struct aml_aac_config *aac_config) { aac_config->format = 1; // AUDIO_FORMAT_PCM_16_BIT aac_config->bits_per_sample = 16; aac_config->channels = 2; aac_config->aot = AOT_AAC_LC; aac_config->sample_rate = 48000; aac_config->afterburner = 1; aac_config->eld_sbr = 0; aac_config->vbr = 0; switch (aac_config->bitrate) { case ENC_BIT_48K: aac_config->bitrate = 48000; break; case ENC_BIT_56K: aac_config->bitrate = 56000; break; case ENC_BIT_64K: aac_config->bitrate = 64000; break; case ENC_BIT_80K: aac_config->bitrate = 80000; break; case ENC_BIT_112K: aac_config->bitrate = 112000; break; case ENC_BIT_128K: aac_config->bitrate = 128000; break; case ENC_BIT_160K: aac_config->bitrate = 160000; break; case ENC_BIT_192K: aac_config->bitrate = 192000; break; case ENC_BIT_224K: aac_config->bitrate = 224000; break; case ENC_BIT_256K: aac_config->bitrate = 256000; break; case ENC_BIT_320K: aac_config->bitrate = 320000; break; default: aac_config->bitrate = 128000; break; } return 0; } int aml_encoder_config_prepare(aml_enc_config_t *enc_config) { enc_encoding_format_t enc_fmt = enc_config->format; switch (enc_fmt) { case ENC_ENCODE_AAC: { enc_config->aac_config.bitrate = enc_config->bitrate; aac_encode_config_prepare(&(enc_config->aac_config)); break; } default: break; } return 0; }