一、概述
IOTC通道是其他通道(AV或RDT通道)的基础,默认情况下,每个连接最多可以创建32个通道(如需更多通道,如DVR/NVR场景,需修改SDK限制)。在RDT及AV通道中,默认以IOTC_Channel_ID=0为主通道,用于实时音视频观看、对讲等操作。
部分功能(如事件回放、事件下载、文件上传/下载等)需频繁创建新通道,因此通道的高效管理对功能体验至关重要。
二、IOTC空闲通道的获取
1. SDK API获取
IOTCAPIs提供IOTC_Session_Get_Free_Channel接口,用于获取指定SID的空闲通道,默认返回当前最小可用通道。
// 获取指定SID的空闲通道
int channel = IOTC_Session_Get_Free_Channel(sid);
调用成功返回[0,31]范围内的通道号;获取失败时常见的错误码:
注意:高频次操作(如快速点击)场景下,可能出现通道被占用的情况。
2. 手动获取
IOTCAPIs支持上层自行指定空闲IOTC通道,通道号需遵循SDK默认范围[0,31]。推荐实现方式:从当前通道(首次从1开始)遍历至31号通道,找到未占用通道后标记为已使用。
完整实现示例如下:
#define _USER_DEFINE_MAX_SESSION_NUMBER_ 8
typedef struct {
int currentChannelPosition;
unsigned int channelStatu;
pthread_mutex_t lock;
} stChannelStatuInSession;
static stChannelStatuInSession stChannelInfos[_USER_DEFINE_MAX_SESSION_NUMBER_];
static void initChannelStatus()
{
// 初始化互斥锁(默认属性)
int ret = pthread_mutex_init(&cm->lock, NULL);
if (ret != 0) {
printf("init mutex failed:%d\n", ret);
return;
}
for (int i = 0; i < _USER_DEFINE_MAX_SESSION_NUMBER_; i++) {
stChannelInfos[i].channelStatu = 0U;
stChannelInfos[i].currentChannelPosition = 31;
}
}
static int getFreeChannelOfSession(unsigned int sid)
{
// 校验位号有效性(仅支持0~31位)
if (sid >= _USER_DEFINE_MAX_SESSION_NUMBER_) {
return -1;
}
int ret = pthread_mutex_lock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_lock failed:%d\n", ret);
return -1;
}
int start = (stChannelInfos[sid].currentChannelPosition + 1) % 32; // 下次查找起始位置
for (int i = 0; i < 32; i++) {
int target_ch = (start + i) % 32; // 当前检查的通道号(循环查找)
// 检查通道是否空闲(对应位为0)
if (!(stChannelInfos[sid].channelStatu & (1U << target_ch))) {
// 标记通道为占用(对应位置1)
if (!target_ch) {
continue;
}
printf("get free channel:%d(last:%d -> current:%d)\n",
target_ch, stChannelInfos[sid].currentChannelPosition, target_ch);
stChannelInfos[sid].channelStatu |= (1U << target_ch);
stChannelInfos[sid].currentChannelPosition = target_ch; // 更新上次分配记录
ret = pthread_mutex_unlock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return target_ch;
}
}
ret = pthread_mutex_unlock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return -1;
}
int freeChannelOfSession(unsigned int sid, int channel) {
// 校验位号有效性
if (channel <= 0="" channel=""> 31 || sid >= _USER_DEFINE_MAX_SESSION_NUMBER_) {
return -1;
}
int ret = pthread_mutex_lock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_lock failed:%d\n", ret);
return -1;
}
// 检查通道是否已占用(对应位为1)
if (stChannelInfos[sid].channelStatu & (1U << channel)) {
stChannelInfos[sid].channelStatu &= ~(1U << channel);
printf("free:%d\n", channel);
ret = pthread_mutex_unlock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return 0;
}
ret = pthread_mutex_unlock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
printf("free failed\n", channel);
return -1;
}
static void ChannelStatusPrintf(int sid)
{
printf("\n===current status[sid=%d]===\n", sid);
printf("channel:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31\n");
printf("status :");
int ret = pthread_mutex_lock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_lock failed:%d\n", ret);
return;
}
for (int i = 0; i < 32; i++) {
if (stChannelInfos[sid].channelStatu & (1U << i)) {
printf("1 "); // 占用
} else {
printf("0 "); // 空闲
}
}
ret = pthread_mutex_unlock(&cm->lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return;
}
printf("\nstatus:1=used,0=free\n\n");
}
说明:示例中通过互斥锁保证通道操作的线程安全,使用位运算高效管理32个通道的占用状态,支持通道分配、释放及状态打印功能。