void *aenc_thread_func2(void *data)
{
int ret;
struct test_resource *res = (struct test_resource *)data;
AUDIO_STREAM_S stream_audio;
struct timeval timeout_val;
fd_set read_fds;
XMEDIA_S32 aenc_fd;
XMEDIA_S32 chn_num;
aenc_fd = XMEDIA_API_AENC_GetFd(res->aenc_chn);
if (aenc_fd < 0)
{
DEMO_PRINT("XMEDIA_API_AENC_GetFd failed with %#x!\n", aenc_fd);
return NULL;
}
if (res->venc_snap == XMEDIA_TRUE)
{
chn_num = res->venc_chn_num - 1;
}
else
{
chn_num = res->venc_chn_num;
}
while (res->aenc_thread_run)
{
FD_ZERO(&read_fds);
FD_SET(aenc_fd, &read_fds);
timeout_val.tv_sec = 1;
timeout_val.tv_usec = 0;
ret = select(aenc_fd + 1, &read_fds, NULL, NULL, &timeout_val);
if (ret < 0)
{
DEMO_PRINT("select failed!\n");
break;
}
else if (ret == 0)
{
DEMO_PRINT("get aenc stream time out, exit thread\n");
continue;
}
else
{
if (FD_ISSET(aenc_fd, &read_fds))
{
ret = XMEDIA_API_AENC_GetStream(res->aenc_chn, &stream_audio, XMEDIA_FALSE);
if (ret != XMEDIA_SUCCESS)
{
DEMO_PRINT("XMEDIA_API_AENC_GetStream(%d), failed(0x%x)!\n", res->aenc_chn, ret);
return NULL;
}
if (res->save_mode == 1)
{
/* save audio stream to file */
(XMEDIA_VOID) fwrite(stream_audio.pStream, 1, stream_audio.u32Len, res->fd_for_mic[0]);
}
else if (res->save_mode == 0)
{
for (int i = 0; i < chn_num; i++)
{
app_liveserver_send_audio_data(i, res->aenc_type, &stream_audio);
}
}
/* finally you must release the stream */
ret = XMEDIA_API_AENC_ReleaseStream(res->aenc_chn, &stream_audio);
if (ret != XMEDIA_SUCCESS)
{
DEMO_PRINT("%s: XMEDIA_API_AENC_ReleaseStream(%d), failed(0x%x)\n", __FUNCTION__, res->aenc_chn, ret);
return NULL;
}
}
}
}
return NULL;
}
XMEDIA_S32 video_chn_request_key_frame(xcam_handle venc_handle, xcam_void *param)
{
VENC_CHN venc_chn;
XMEDIA_S32 ret;
venc_chn = (VENC_CHN)venc_handle;
ret = XMEDIA_API_VENC_RequestIDR(venc_chn, XMEDIA_TRUE); // 请求IDR帧 第二个参数代表使能立刻解码IDR帧
if (XMEDIA_SUCCESS != ret)
{
DEMO_PRINT("VENC_RequestIDR(chn:%d) faild with%#x!\n", venc_chn, ret);
return XMEDIA_FAILURE;
}
else
{
DEMO_PRINT("VENC_RequestIDR(chn:%d) successful!\n", venc_chn);
}
return ret;
}
void save_init(struct test_resource *res)
{
XMEDIA_S32 ret;
XMEDIA_S32 i;
char save_file[256] = {0};
XMEDIA_S32 chn_num;
if (res->venc_snap == XMEDIA_TRUE)
{
chn_num = res->venc_chn_num - 1;
}
else
{
chn_num = res->venc_chn_num;
}
if (res->save_mode == 1)
{
XMEDIA_U32 width = 0;
XMEDIA_U32 height = 0;
for (i = 0; i < chn_num; i++)
{
memset(save_file, 0, sizeof(save_file));
if (i == 0)
{
width = res->big_image_size.u32Width;
height = res->big_image_size.u32Height;
}
else if (i == 1)
{
width = res->small_image_size.u32Width;
height = res->small_image_size.u32Height;
}
else
{
width = res->ai_image_size.u32Width;
height = res->ai_image_size.u32Height;
}
snprintf(save_file, 256, "%s%d_%d.%s", res->save_path, width, height, payload_to_string(res->venc_payload[i]));
res->esfile[i] = fopen(save_file, "wb");
}
if (res->audio_enable == XMEDIA_TRUE)
{
memset(save_file, 0, sizeof(save_file));
snprintf(save_file, 256, "%saudio%d.%s", res->save_path, res->aenc_chn, payload_to_string(res->aenc_type));
res->fd_for_mic[0] = fopen(save_file, "wb");
}
}
else if (res->save_mode == 0)
{
ret = app_liveserver_init();
CHECK_RET_SUCCESS(ret);
}
for (i = 0; i < chn_num; i++)
{
if (res->save_mode == 0)
{
xcam_track_video_source_info track_video;
xcam_track_audio_source_info track_audio;
xcam_handle aenc_handle = -1;
if (res->audio_enable == XMEDIA_TRUE)
{
aenc_handle = 0;
}
app_liveserver_get_video_src_info(i, res, &track_video); // 获取视频源信息
app_liveserver_get_audio_src_info(aenc_handle, res, &track_audio); // 获取音频源信息
ret =
(i, &track_video,
aenc_handle, &track_audio, (const xcam_char *)g_stream_name[i],
video_chn_request_key_frame); // 添加流至liveserver中 video_chn_request_key_frame->请求关键帧
if (ret != XMEDIA_SUCCESS)
{
printf("Liveserver add stream venc_handle[%u] failed! \n\n", i);
return;
}
}
}
return;
}
void save_deinit(struct test_resource *res)
{
XMEDIA_S32 i;
XMEDIA_S32 chn_num;
if (res->venc_snap == XMEDIA_TRUE)
{
chn_num = res->venc_chn_num - 1;
}
else
{
chn_num = res->venc_chn_num;
}
if (res->save_mode == 1)
{
for (i = 0; i < chn_num; i++)
{
fclose(res->esfile[i]);
}
fclose(res->fd_for_mic[0]);
}
else if (res->save_mode == 0)
{
app_liveserver_deinit();
}
return;
}
// static int16_t linear_interpolate(int16_t y1, int16_t y2, float t) {
// return y1 + (int16_t)((y2 - y1) * t);
// }
// static void resample_8000_to_16000(int16_t *src_samples, int src_length, int16_t *dst_samples) {
// int i;
// int dst_length = src_length * 2;
// for (i = 0; i < src_length - 1; i++) {
// dst_samples[i * 2] = src_samples[i]; // 原始采样点
// dst_samples[i * 2 + 1] = linear_interpolate(src_samples[i], src_samples[i + 1], 0.5); // 插值点
// }
// // 处理最后一个采样点
// dst_samples[(src_length - 1) * 2] = src_samples[src_length - 1];
// dst_samples[(src_length - 1) * 2 + 1] = src_samples[src_length - 1];
// }
void play_audio_file(char *filepath)
{
printf("[%s]open %s\n", __func__, filepath);
XMEDIA_S32 ret;
// struct test_resource *p_t = (struct test_resource *)arg;
XMEDIA_S32 adec_chn = g_adec_chn;
printf("into play_audio_file adec_chn %d \n", (int)adec_chn);
AUDIO_STREAM_S stream;
int audio_play_file = 1;
#if USE_XY == 1
// PCM 2 AAC
XMEDIA_U32 len = 320;
#else
XMEDIA_U32 len = 640;
#endif
XMEDIA_U32 read_len = 0;
XMEDIA_U8 *audio_stream = NULL;
// XMEDIA_S32 adec_chn = p_t->adec_chn;
// adec_chn
audio_stream = (XMEDIA_U8 *)malloc(sizeof(XMEDIA_U8) * len * 2);
if (NULL == audio_stream)
{
printf("%s: malloc failed!\n", __FUNCTION__);
return NULL;
}
FILE *audio_fp = NULL;
int play_flag = 0;
long filesize = 0;
long count_audio_len = 0;
while (1)
{
stream.pStream = audio_stream;
// 1.获取文件并输出
// 进行操作
// a.打开音频文件
// printf("into audio_fp\n");
if (play_flag == 0)
{
printf("into play_speaker:play_flag = 0\n");
audio_fp = fopen(filepath, "rb");
if (audio_fp == NULL)
{
perror("open audio.pcm failed\n");
continue;
}
fseek(audio_fp, 0, SEEK_END); // 移动到文件末尾
filesize = ftell(audio_fp); // 获取当前位置,即文件大小
printf("文件 '%s' 的大小是 %ld 字节。\n", filepath, filesize);
play_flag = 1;
fseek(audio_fp, 0, SEEK_SET);
continue;
}
else
{
// printf("into play_speaker:play_flag = 1\n");
// read_len = fread(stream.pStream, 1, len*2, audio_fp);
// printf("准备读取的 len*2 = %d\n", len*2);
// printf("当前文件位置:%ld\n", ftell(audio_fp));
// printf("stream.pStream 地址: %p\n", (void*)stream.pStream);
read_len = fread(stream.pStream, 1, len * 2, audio_fp);
if (ferror(audio_fp))
{
perror("读取文件时发生错误");
clearerr(audio_fp);
}
if (read_len > 0)
{
stream.u32Len = read_len;
count_audio_len += read_len;
// printf("此次读取了 %ld 字节,总共读取了 %ld 字节。\n", read_len, count_audio_len);
if (count_audio_len >= filesize)
{
count_audio_len = 0;
play_flag = 0;
printf("播放结束\n");
fclose(audio_fp);
audio_fp = NULL;
ret = XMEDIA_API_ADEC_SendEndOfStream(adec_chn, XMEDIA_FALSE);
if (XMEDIA_SUCCESS != ret)
{
AUDIO_ERR("%s: XMEDIA_API_ADEC_SendEndOfStream failed(0x%x)\n", __FUNCTION__, ret);
}
break;
}
}
else
{
printf("无数据或错误,可能已到文件末尾\n");
}
}
if (read_len <= 0)
{
continue;
}
stream.u32Len = read_len;
ret = XMEDIA_API_ADEC_SendStream(adec_chn, &stream, XMEDIA_TRUE);
if (XMEDIA_SUCCESS != ret)
{
AUDIO_ERR("%s: XMEDIA_API_ADEC_SendStream(%d) failed(0x%x)\n", __FUNCTION__, adec_chn, ret);
break;
}
}
if (audio_fp != NULL)
{
fclose(audio_fp);
}
if (audio_stream != NULL)
{
free(audio_stream);
}
}
// TODO 音频解码
void *adec_thread_func2(void *arg)
{
XMEDIA_S32 ret;
struct test_resource *p_t = (struct test_resource *)arg;
AUDIO_STREAM_S stream;
#if USE_XY == 1
// PCM 2 AAC
XMEDIA_U32 len = 320;
#else
XMEDIA_U32 len = 640;
#endif
XMEDIA_U32 read_len = 0;
XMEDIA_U8 *audio_stream = NULL;
XMEDIA_S32 adec_chn = p_t->adec_chn;
// adec_chn
audio_stream = (XMEDIA_U8 *)malloc(sizeof(XMEDIA_U8) * len * 2);
if (NULL == audio_stream)
{
printf("%s: malloc failed!\n", __FUNCTION__);
return NULL;
}
while (p_t->adec_thread_run)
{
/* read from file */
stream.pStream = audio_stream;
QrcodePacket *p = (QrcodePacket *)que_pop(g_que_r);
if (!p)
{
printf("packet is null\n");
exit(0);
}
read_len = p->dat1;
#if USE_XY == 1
// static long i = 0;
// if (!(i++ % 100))
// {
// printf("|read_len = %d\n", read_len);
// /* code */
// i -= 100;
// }
// PCM 2 AAC
// 传入8000Hz 但需要传出16000
#endif
// int16_t dst_samples[320];
// // 调用重采样函数
// resample_8000_to_16000(p->address, read_len, dst_samples);
memcpy(stream.pStream, p->address, read_len);
int nty = 0;
nty = p->dat2;
if (nty == 99)
{
pool_push(g_pPool_r, (void *)p);
break;
}
pool_push(g_pPool_r, (void *)p);
if (read_len <= 0)
{
/*
ret = XMEDIA_API_ADEC_SendEndOfStream(adec_chn, XMEDIA_FALSE);
if (XMEDIA_SUCCESS != ret) {
AUDIO_ERR("%s: XMEDIA_API_ADEC_SendEndOfStream failed(0x%x)\n", __FUNCTION__, ret);
}
*/
continue;
}
stream.u32Len = read_len;
// #if USE_XY == 1
// //PCM 2 AAC
// #else
// stream.u32Len = read_len/2;
// #endif
// printf("adec_thread_func2 ---------------%d\n", (int)stream.u32Len);
ret = XMEDIA_API_ADEC_SendStream(adec_chn, &stream, XMEDIA_TRUE);
if (XMEDIA_SUCCESS != ret)
{
AUDIO_ERR("%s: XMEDIA_API_ADEC_SendStream(%d) failed(0x%x)\n", __FUNCTION__, adec_chn, ret);
break;
}
if (!(p_t->adec_thread_run))
{
XMEDIA_API_ADEC_DestroyChn(adec_chn);
break;
}
}
if (audio_stream != NULL)
{
free(audio_stream);
}
}
注释一下代码
最新发布