一、概述
IOTC通道是其他通道(AV或RDT通道)封裝的基礎(chǔ),默認(rèn)情況下,每個(gè)連接最多可以創(chuàng)建32個(gè)通道(如需更多通道,如DVR/NVR場景,需修改SDK限制)。在RDT及AV通道中,默認(rèn)以
IOTC_Channel_ID=0為主通道,用于實(shí)時(shí)音視頻觀看、對講等操作。部分功能(如事件回放、事件下載、文件上傳/下載等)可能會需頻繁或者快速地創(chuàng)建/銷毀子通道,因此,通道的高效管理策略對功能體驗(yàn)至關(guān)重要。
二、IOTC空閑通道的獲取
1. SDK API獲取
IOTCAPIs已提供
IOTC_Session_Get_Free_Channel接口,用于獲取指定SID的空閑通道,默認(rèn)返回當(dāng)前最小可用的通道,使用方式可以參考:// 獲取指定SID的空閑通道
int channel = IOTC_Session_Get_Free_Channel(sid);
調(diào)用成功返回[0,31]范圍內(nèi)的通道號;獲取失敗時(shí)常見的錯(cuò)誤碼:
- -14:SID無效
- -18:無空閑通道
注意事項(xiàng)
高頻次操作(如快速點(diǎn)擊)場景下,可能出現(xiàn)通道被占用的情況。
2. 手動(dòng)獲取
IOTCAPIs支持上層自行指定空閑IOTC通道,通道號需遵循SDK默認(rèn)范圍[0,31]。推薦實(shí)現(xiàn)方式:從當(dāng)前通道(首次從1開始)遍歷至31號通道,找到未占用通道后標(biāo)記為已使用。此邏輯的設(shè)計(jì),使SDK在短期內(nèi)不會拿到相同的IOTC通道,避免出現(xiàn)通道未來得及釋放導(dǎo)致被占用的情形:
- 第一次:使用IOTC_Channel_ID=1(如已被占用,自動(dòng)加1)
- 第二次:使用IOTC_Channel_ID=2(如已被占用,自動(dòng)加1)
- 第三次:使用IOTC_Channel_ID=3(如已被占用,自動(dòng)加1)
- ...
- 第三十二次:使用IOTC_Channel_ID=1(已超出31的范圍,自動(dòng)從1開始,如已被占用,自動(dòng)加1)
實(shí)現(xiàn)示例
初始化
#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() {
// 初始化互斥鎖(默認(rèn)屬性)
int ret = pthread_mutex_init(&stChannelInfos[sid].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) {
// 校驗(yàn)位號有效性(僅支持0~31位)
if (sid >= _USER_DEFINE_MAX_SESSION_NUMBER_) {
return -1;
}
int ret = pthread_mutex_lock(&stChannelInfos[sid].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; // 當(dāng)前檢查的通道號(循環(huán)查找)
// 檢查通道是否空閑(對應(yīng)位為0)
if (!(stChannelInfos[sid].channelStatu & (1U << target_ch))) {
// 標(biāo)記通道為占用(對應(yīng)位置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(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return target_ch;
}
}
ret = pthread_mutex_unlock(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return -1;
}
釋放通道
int freeChannelOfSession(unsigned int sid, int channel) {
// 校驗(yàn)位號有效性
if (channel <= 0="" channel=""> 31 || sid >= _USER_DEFINE_MAX_SESSION_NUMBER_) {
return -1;
}
int ret = pthread_mutex_lock(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_lock failed:%d\n", ret);
return -1;
}
// 檢查通道是否已占用(對應(yīng)位為1)
if (stChannelInfos[sid].channelStatu & (1U << channel)) {
stChannelInfos[sid].channelStatu &= ~(1U << channel);
printf("free:%d\n", channel);
ret = pthread_mutex_unlock(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
return 0;
}
ret = pthread_mutex_unlock(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return -1;
}
printf("free failed\n", channel);
return -1;
}
通道狀態(tài)打印
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(&stChannelInfos[sid].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(&stChannelInfos[sid].lock);
if (ret != 0) {
printf("pthread_mutex_unlock failed:%d\n", ret);
return;
}
printf("\nstatus:1=used,0=free\n\n");
}
說明:示例中考慮嵌入式內(nèi)存資源有限,僅用位來存儲對應(yīng)通道的狀態(tài),通過互斥鎖保證通道操作的線程安全,使用位運(yùn)算高效管理32個(gè)通道的占用狀態(tài),支持通道分配、釋放及狀態(tài)打印功能。
