针对VENC读取数据时AO输出噪音的问题,结合代码实现的分析,以下是关键解决步骤和代码修正方向:
venc_stream 结构体未初始化导致随机内存数据被读取pack_cnt 未设置导致编码器无法正确输出数据流kd_mpi_venc_query_status() 导致无法判断帧是否就绪timeout=-1) 导致音频输出线程被长时间阻塞// 修复步骤 1: 初始化venc_stream结构体
k_venc_stream venc_stream;
memset(&venc_stream, 0, sizeof(venc_stream)); // 关键初始化!
// 修复步骤 2: 设置有效的pack_cnt
venc_stream.pack_cnt = 1; // 根据实际需求设置包数量
venc_stream.pack = (k_venc_pack*)malloc(sizeof(k_venc_pack) * venc_stream.pack_cnt);
// 新增: 查询编码状态机制
k_venc_chn_status status;
while (1) {
// 修复步骤 3: 先查询帧状态 (关键添加!)
if (kd_mpi_venc_query_status(venc_chn, &status) == 0) {
if (status.cur_packs > 0) { // 有数据包就绪才获取
// 修复步骤 4: 使用非阻塞获取方式 (解决噪音关键)
int ret = kd_mpi_venc_get_stream(venc_chn, &venc_stream, 50); // 超时50ms
if (ret == 0) {
/* 处理视频数据 */
kd_mpi_venc_release_stream(venc_chn, &venc_stream);
}
}
}
// 新增: 添加线程休眠(降低CPU占用)
usleep(10 * 1000); // 10ms休眠,让出CPU资源
}
// 修复步骤 5: 增加资源释放(防止内存泄漏)
free(venc_stream.pack);结构体初始化:
memset(&venc_stream, 0, sizeof(venc_stream));确保所有指针和计数器初始为0,避免野指针导致崩溃
pack_cnt设置:
venc_stream.pack_cnt = 1; // 单包模式(根据SDK要求调整)
venc_stream.pack = malloc(...); // 动态分配内存状态查询优先:
kd_mpi_venc_query_status(venc_chn, &status);
if (status.cur_packs > 0) { ... }避免无数据时的无效阻塞调用
非阻塞超时设置:
kd_mpi_venc_get_stream(venc_chn, &venc_stream, 50); // 50ms超时防止长期阻塞音频线程("哒哒声"的根本原因)
添加CPU资源释放:
usleep(10*1000); // 主动休眠10ms确保音频线程获得足够的CPU时间片
// 在音频输出线程中加入优先级设置
struct sched_param param = {.sched_priority = 90};
pthread_setschedparam(audio_thread, SCHED_FIFO, ¶m);
调试提示:使用
top -H监控线程CPU占用率,确认音频线程没有被视频编码线程完全阻塞。典型的哒哒声往往是由于音频buffer未被及时填充导致的硬件噪声。
通过以上修改,可以解决因VENC阻塞调用导致音频输出资源被抢占引起的哒哒声问题,同时保证视频流的正常获取。务必根据实际SDK调整 pack_cnt 和超时参数值。
举报
更多回帖