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.
647 lines
18 KiB
647 lines
18 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights reserved.
|
|
* Description: aenc sample
|
|
* Author: audio
|
|
* Create: 2019-09-17
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
|
|
#include "uapi_system.h"
|
|
#include "uapi_aenc.h"
|
|
|
|
#include "ha_codec_aacenc.h"
|
|
#include "ha_codec_g711.h"
|
|
#include "ha_codec_g722.h"
|
|
#include "ha_codec_amrnb.h"
|
|
#include "ha_codec_amrwb.h"
|
|
|
|
#include "drv_audio_ext.h"
|
|
#include "adp_uapi_ext.h"
|
|
#include "securec.h"
|
|
|
|
typedef struct {
|
|
td_char *sample;
|
|
td_char *in_stream;
|
|
td_char *in_channels;
|
|
td_char *in_sample_rate;
|
|
td_char *out_stream;
|
|
td_char *out_stream_type;
|
|
} input_arg;
|
|
|
|
typedef struct _sample_ctx {
|
|
FILE *in_stream;
|
|
td_u32 in_channels;
|
|
td_u32 in_sample_rate;
|
|
FILE *out_stream;
|
|
td_u32 out_stream_type;
|
|
|
|
td_bool stop;
|
|
pthread_t put_thread;
|
|
pthread_t get_thread;
|
|
|
|
td_handle aenc;
|
|
|
|
td_s32 (*aenc_create)(struct _sample_ctx *aenc_ctx);
|
|
} sample_aenc_ctx;
|
|
|
|
#define AENC_IN_PACKET_SIZE (1024 * 4)
|
|
#define AENC_SLEEP_TIME (5 * 1000) /* 5ms */
|
|
#define AENC_SEND_SLEEP_TIME (10 * 1000) /* 10ms */
|
|
|
|
static td_void audio_frame_init(const sample_aenc_ctx *aenc_ctx, uapi_audio_frame *frame)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = memset_s(frame, sizeof(*frame), 0, sizeof(uapi_audio_frame));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return;
|
|
}
|
|
|
|
frame->sample_rate = aenc_ctx->in_sample_rate;
|
|
frame->bit_depth = UAPI_AUDIO_BIT_DEPTH_16;
|
|
frame->channels = aenc_ctx->in_channels;
|
|
frame->pcm_samples = AENC_IN_PACKET_SIZE / (frame->channels * sizeof(td_s16));
|
|
frame->interleaved = TD_TRUE;
|
|
}
|
|
|
|
static td_void *aenc_get_thread(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 frames = 0;
|
|
sample_aenc_ctx *aenc_ctx = (sample_aenc_ctx *)arg;
|
|
uapi_es_buf buf = { 0 };
|
|
|
|
while (aenc_ctx->stop == TD_FALSE) {
|
|
ret = uapi_aenc_acquire_stream(aenc_ctx->aenc, &buf, 0);
|
|
if (ret != TD_SUCCESS) {
|
|
usleep(AENC_SLEEP_TIME);
|
|
continue;
|
|
}
|
|
|
|
(td_void)fwrite(buf.buf, 1, buf.buf_len, aenc_ctx->out_stream);
|
|
|
|
if ((++frames % 0x1000) == 0) { /* print every 1024 frames */
|
|
printf("uapi_aenc_acquire_stream frames = 0x%x\n", frames);
|
|
}
|
|
|
|
ret = uapi_aenc_release_stream(aenc_ctx->aenc, &buf);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_release_stream failed(0x%x)\n", ret);
|
|
return TD_NULL;
|
|
}
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
static td_void *aenc_put_thread(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 read_size;
|
|
td_u32 encode_frame = 0;
|
|
td_bool send = TD_TRUE;
|
|
td_void *data = TD_NULL;
|
|
uapi_audio_frame ao_frame;
|
|
sample_aenc_ctx *aenc_ctx = (sample_aenc_ctx *)arg;
|
|
|
|
audio_frame_init(aenc_ctx, &ao_frame);
|
|
|
|
data = (td_void *)malloc(AENC_IN_PACKET_SIZE);
|
|
if (data == TD_NULL) {
|
|
printf("malloc buffer failed!\n");
|
|
return TD_NULL;
|
|
}
|
|
|
|
ao_frame.pcm_buffer = (td_s32 *)data;
|
|
|
|
while (aenc_ctx->stop == TD_FALSE) {
|
|
if (send == TD_TRUE) {
|
|
read_size = (td_s32)fread(data, 1, AENC_IN_PACKET_SIZE, aenc_ctx->in_stream);
|
|
if (read_size != AENC_IN_PACKET_SIZE) {
|
|
printf("read file end and rewind!\n");
|
|
rewind(aenc_ctx->in_stream);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
ao_frame.frame_index = encode_frame;
|
|
ret = uapi_aenc_send_frame(aenc_ctx->aenc, &ao_frame);
|
|
if (ret == TD_SUCCESS) {
|
|
send = TD_TRUE;
|
|
encode_frame++;
|
|
} else {
|
|
send = TD_FALSE;
|
|
usleep(AENC_SEND_SLEEP_TIME);
|
|
}
|
|
}
|
|
|
|
free(data);
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
static td_s32 aac_aenc_create(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
uapi_aenc_attr aenc_attr;
|
|
ha_codec_aac_enc_config private_config;
|
|
ha_codec_enc_param param;
|
|
trans_enc_param_uapi_to_mpi(&(aenc_attr.param), ¶m);
|
|
|
|
if ((aenc_ctx->in_channels != 1) && (aenc_ctx->in_channels != UAPI_AUDIO_CHANNEL_2)) {
|
|
printf("aac encoder only support stero/mono input!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_register_encoder("libHA.AUDIO.AAC.encode.so");
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_register_encoder failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("register \"libHA.AUDIO.AAC.encode.so\" success!\n");
|
|
|
|
ret = memset_s(&aenc_attr, sizeof(aenc_attr), 0, sizeof(uapi_aenc_attr));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = memset_s(&private_config, sizeof(ha_codec_aac_enc_config),
|
|
0, sizeof(ha_codec_aac_enc_config));
|
|
if (ret != EOK) {
|
|
printf("private_config memset fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_attr.aenc_type = UAPI_ACODEC_ID_AAC;
|
|
ha_codec_aac_get_default_config(&private_config);
|
|
private_config.sample_rate = (td_s32)aenc_ctx->in_sample_rate;
|
|
|
|
ha_codec_aac_get_enc_default_open_param(¶m, (td_void *)&private_config);
|
|
trans_enc_param_mpi_to_uapi(&(aenc_attr.param), ¶m);
|
|
ret = uapi_aenc_create(&aenc_attr, &aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 g711_aenc_create(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
uapi_aenc_attr aenc_attr;
|
|
ha_codec_g711_encode_open_config private_config;
|
|
ha_codec_enc_param param;
|
|
trans_enc_param_uapi_to_mpi(&(aenc_attr.param), ¶m);
|
|
|
|
/* g711 encoder only support 8k/16bit/mono */
|
|
if ((aenc_ctx->in_channels != 1) || (aenc_ctx->in_sample_rate != UAPI_AUDIO_SAMPLE_RATE_8K)) {
|
|
printf("g711 encoder only support 8k/16bit/mono input!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_register_encoder("libHA.AUDIO.G711.codec.so");
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_register_encoder failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("register \"libHA.AUDIO.G711.codec.so\" success!\n");
|
|
|
|
ret = memset_s(&aenc_attr, sizeof(aenc_attr), 0, sizeof(uapi_aenc_attr));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = memset_s(&private_config, sizeof(ha_codec_g711_encode_open_config),
|
|
0, sizeof(ha_codec_g711_encode_open_config));
|
|
if (ret != EOK) {
|
|
printf("private_config memset fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_attr.aenc_type = UAPI_ACODEC_ID_G711;
|
|
private_config.is_alaw = 1;
|
|
private_config.vad = TD_TRUE;
|
|
|
|
ha_codec_g711_get_enc_default_open_param(¶m, (td_void *)&private_config);
|
|
trans_enc_param_mpi_to_uapi(&(aenc_attr.param), ¶m);
|
|
aenc_attr.param.sample_per_frame = G711_FRAME_LEN;
|
|
|
|
ret = uapi_aenc_create(&aenc_attr, &aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 g722_aenc_create(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
uapi_aenc_attr aenc_attr;
|
|
ha_codec_enc_param param;
|
|
trans_enc_param_uapi_to_mpi(&(aenc_attr.param), ¶m);
|
|
|
|
if ((aenc_ctx->in_channels != 1) || (aenc_ctx->in_sample_rate != UAPI_AUDIO_SAMPLE_RATE_16K)) {
|
|
printf("g722 encoder only support 16k/16bit/mono input!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_register_encoder("libHA.AUDIO.G722.codec.so");
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_register_encoder failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("register \"libHA.AUDIO.G722.codec.so\" success!\n");
|
|
|
|
ret = memset_s(&aenc_attr, sizeof(aenc_attr), 0, sizeof(uapi_aenc_attr));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_attr.aenc_type = UAPI_ACODEC_ID_G722;
|
|
|
|
ha_codec_g722_get_enc_default_open_param(¶m);
|
|
trans_enc_param_mpi_to_uapi(&(aenc_attr.param), ¶m);
|
|
ret = uapi_aenc_create(&aenc_attr, &aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 amr_wb_aenc_create(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
uapi_aenc_attr aenc_attr;
|
|
ha_codec_amrwb_encode_open_config private_config;
|
|
ha_codec_enc_param param;
|
|
trans_enc_param_uapi_to_mpi(&(aenc_attr.param), ¶m);
|
|
|
|
if ((aenc_ctx->in_channels != 1) || (aenc_ctx->in_sample_rate != UAPI_AUDIO_SAMPLE_RATE_16K)) {
|
|
printf("amw-wb encoder only support 16k/16bit/mono input!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_register_encoder("libHA.AUDIO.AMRWB.codec.so");
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_register_encoder failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("register \"libHA.AUDIO.AMRWB.codec.so\" success!\n");
|
|
|
|
ret = memset_s(&aenc_attr, sizeof(aenc_attr), 0, sizeof(uapi_aenc_attr));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = memset_s(&private_config, sizeof(ha_codec_amrwb_encode_open_config),
|
|
0, sizeof(ha_codec_amrwb_encode_open_config));
|
|
if (ret != EOK) {
|
|
printf("private_config memset fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_attr.aenc_type = UAPI_ACODEC_ID_AMRWB;
|
|
private_config.format = HA_CODEC_AMRWB_FORMAT_MIME;
|
|
private_config.mode = HA_CODEC_AMRWB_MR2385;
|
|
private_config.dtx = TD_FALSE;
|
|
|
|
ha_codec_amrwb_get_enc_default_open_param(¶m, (td_void *)&private_config);
|
|
trans_enc_param_mpi_to_uapi(&(aenc_attr.param), ¶m);
|
|
ret = uapi_aenc_create(&aenc_attr, &aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 amr_nb_aenc_create(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
uapi_aenc_attr aenc_attr;
|
|
ha_codec_amrnb_encode_open_config private_config;
|
|
ha_codec_enc_param param;
|
|
trans_enc_param_uapi_to_mpi(&(aenc_attr.param), ¶m);
|
|
|
|
if ((aenc_ctx->in_channels != 1) || (aenc_ctx->in_sample_rate != UAPI_AUDIO_SAMPLE_RATE_8K)) {
|
|
printf("amw-nb encoder only support 8k/16bit/mono input!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_register_encoder("libHA.AUDIO.AMRNB.codec.so");
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_register_encoder failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("register \"libHA.AUDIO.AMRNB.codec.so\" success!\n");
|
|
|
|
ret = memset_s(&aenc_attr, sizeof(aenc_attr), 0, sizeof(uapi_aenc_attr));
|
|
if (ret != EOK) {
|
|
printf("memset_s fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = memset_s(&private_config, sizeof(ha_codec_amrnb_encode_open_config),
|
|
0, sizeof(ha_codec_amrnb_encode_open_config));
|
|
if (ret != EOK) {
|
|
printf("private_config memset fail(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_attr.aenc_type = UAPI_ACODEC_ID_AMRNB;
|
|
private_config.format = HA_CODEC_AMRNB_MIME;
|
|
private_config.mode = HA_CODEC_AMRNB_MR475;
|
|
private_config.dtx = TD_FALSE;
|
|
|
|
ha_codec_amrnb_get_enc_default_open_param(¶m, (td_void *)&private_config);
|
|
trans_enc_param_mpi_to_uapi(&(aenc_attr.param), ¶m);
|
|
ret = uapi_aenc_create(&aenc_attr, &aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("uapi_aenc_create failed(0x%x)\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
typedef struct {
|
|
const td_char *name;
|
|
td_u32 codec_id;
|
|
td_s32 (*aenc_create)(sample_aenc_ctx *aenc_ctx);
|
|
} acodec_map;
|
|
|
|
static const acodec_map g_aenc_map[] = {
|
|
{"aac", UAPI_ACODEC_ID_AAC, aac_aenc_create},
|
|
{"g711", UAPI_ACODEC_ID_G711, g711_aenc_create},
|
|
{"g722", UAPI_ACODEC_ID_G722, g722_aenc_create},
|
|
{"amrwb", UAPI_ACODEC_ID_AMRWB, amr_wb_aenc_create},
|
|
{"amrnb", UAPI_ACODEC_ID_AMRNB, amr_nb_aenc_create},
|
|
};
|
|
|
|
static td_void aenc_deinit(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = uapi_aenc_destroy(aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_aenc_destroy failed(0x%x)\n", ret);
|
|
return;
|
|
}
|
|
|
|
aenc_ctx->aenc = TD_INVALID_HANDLE;
|
|
|
|
ret = uapi_aenc_deinit();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_aenc_deinit failed.\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
static const acodec_map *get_aenc_codec_map(const td_char *name)
|
|
{
|
|
td_u32 i;
|
|
td_u32 num = sizeof(g_aenc_map) / sizeof(g_aenc_map[0]);
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (strcasecmp(name, g_aenc_map[i].name) == 0) {
|
|
return &g_aenc_map[i];
|
|
}
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
static td_s32 aenc_init(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (aenc_ctx->aenc_create == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = uapi_aenc_init();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_aenc_init failed.\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = aenc_ctx->aenc_create(aenc_ctx);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call aenc_ctx->aenc_create failed.\n");
|
|
(td_void)uapi_aenc_deinit();
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void sample_stop(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
|
|
aenc_ctx->stop = TD_TRUE;
|
|
pthread_join(aenc_ctx->get_thread, TD_NULL);
|
|
pthread_join(aenc_ctx->put_thread, TD_NULL);
|
|
|
|
ret = uapi_aenc_stop(aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_aenc_stop failed(0x%x)\n", ret);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_start(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = uapi_aenc_start(aenc_ctx->aenc);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_aenc_start failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
aenc_ctx->stop = TD_FALSE;
|
|
pthread_create(&aenc_ctx->get_thread, TD_NULL, aenc_get_thread, aenc_ctx);
|
|
pthread_create(&aenc_ctx->put_thread, TD_NULL, aenc_put_thread, aenc_ctx);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void sample_ctx_deinit(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
if (aenc_ctx->out_stream != TD_NULL) {
|
|
(td_void)fclose(aenc_ctx->out_stream);
|
|
aenc_ctx->out_stream = TD_NULL;
|
|
}
|
|
|
|
if (aenc_ctx->in_stream != TD_NULL) {
|
|
(td_void)fclose(aenc_ctx->in_stream);
|
|
aenc_ctx->in_stream = TD_NULL;
|
|
}
|
|
|
|
aenc_ctx->aenc = TD_INVALID_HANDLE;
|
|
}
|
|
|
|
static td_s32 sample_ctx_init(const input_arg *arg, sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
const acodec_map *map = get_aenc_codec_map(arg->out_stream_type);
|
|
if (map == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
aenc_ctx->aenc = TD_INVALID_HANDLE;
|
|
aenc_ctx->aenc_create = map->aenc_create;
|
|
|
|
aenc_ctx->in_stream = fopen(arg->in_stream, "rb");
|
|
if (aenc_ctx->in_stream == TD_NULL) {
|
|
printf("open file %s error!\n", arg->in_stream);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
aenc_ctx->in_channels = (td_u32)strtol(arg->in_channels, NULL, 10); /* 10 is Dec */
|
|
aenc_ctx->in_sample_rate = (td_u32)strtol(arg->in_sample_rate, NULL, 10); /* 10 is Dec */
|
|
|
|
aenc_ctx->out_stream = fopen(arg->out_stream, "wb");
|
|
if (aenc_ctx->out_stream == TD_NULL) {
|
|
printf("open file %s error!\n", arg->out_stream);
|
|
goto out;
|
|
}
|
|
|
|
/* write magic number of AMR file */
|
|
if (map->codec_id == UAPI_ACODEC_ID_AMRWB) {
|
|
(td_void)fwrite(HA_CODEC_AMRWB_MAGIC_NUMBER, 1,
|
|
strlen(HA_CODEC_AMRWB_MAGIC_NUMBER), aenc_ctx->out_stream);
|
|
} else if (map->codec_id == UAPI_ACODEC_ID_AMRNB) {
|
|
(td_void)fwrite(HA_CODEC_AMRNB_MAGIC_NUMBER, 1,
|
|
strlen(HA_CODEC_AMRNB_MAGIC_NUMBER), aenc_ctx->out_stream);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
out:
|
|
(td_void)fclose(aenc_ctx->in_stream);
|
|
aenc_ctx->in_stream = TD_NULL;
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
static const struct {
|
|
td_s32 (*init)(sample_aenc_ctx *aenc_ctx);
|
|
td_void (*deinit)(sample_aenc_ctx *aenc_ctx);
|
|
} g_sample_module[] = {
|
|
{aenc_init, aenc_deinit},
|
|
{sample_start, sample_stop},
|
|
};
|
|
|
|
static td_void sample_deinit(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 module;
|
|
const td_s32 num = sizeof(g_sample_module) / sizeof(g_sample_module[0]);
|
|
|
|
for (module = num - 1; module >= 0; module--) {
|
|
g_sample_module[module].deinit(aenc_ctx);
|
|
}
|
|
|
|
ret = uapi_sys_deinit();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_sys_deinit failed(0x%x)\n", ret);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_init(sample_aenc_ctx *aenc_ctx)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 module;
|
|
const td_s32 num = sizeof(g_sample_module) / sizeof(g_sample_module[0]);
|
|
|
|
ret = uapi_sys_init();
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call uapi_sys_init failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
for (module = 0; module < num; module++) {
|
|
ret = g_sample_module[module].init(aenc_ctx);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call init failed(0x%x)\n", ret);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
|
|
out:
|
|
module--;
|
|
for (; module >= 0; module--) {
|
|
g_sample_module[module].deinit(aenc_ctx);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static td_void usage(const input_arg *arg)
|
|
{
|
|
printf("usage: %s infile_name in_channel in_samplerate outfile_name outfile_type\n"
|
|
" infile_name: input file name\n"
|
|
" in_channel:1 2\n"
|
|
" insamplerate:8000 16000\n"
|
|
" outfile_name: output file name\n"
|
|
" outfile_type:aac g711 g722 amrwb amrnb\n",
|
|
arg->sample);
|
|
printf("example: %s ./test.wav 1 8000 ./test.g711 g711\n", arg->sample);
|
|
}
|
|
|
|
td_s32 main(int argc, char *argv[])
|
|
{
|
|
td_s32 ret;
|
|
sample_aenc_ctx aenc_ctx;
|
|
|
|
input_arg *arg = (input_arg *)argv;
|
|
|
|
if (argc != sizeof(input_arg) / sizeof(td_char *)) {
|
|
usage(arg);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = memset_s(&aenc_ctx, sizeof(aenc_ctx), 0, sizeof(sample_aenc_ctx));
|
|
if (ret != EOK) {
|
|
printf("call memset_s failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_ctx_init(arg, &aenc_ctx);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call sample_ctx_init failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_init(&aenc_ctx);
|
|
if (ret != TD_SUCCESS) {
|
|
printf("call sample_init failed(0x%x)\n", ret);
|
|
goto out;
|
|
}
|
|
|
|
printf("press any key to exit\n");
|
|
(td_void)getchar();
|
|
|
|
sample_deinit(&aenc_ctx);
|
|
out:
|
|
sample_ctx_deinit(&aenc_ctx);
|
|
return ret;
|
|
}
|