前言
由于hi3516a海思自带的开发应用程序是通过摄像头接口或HDMI接口获取视频数据后并进行存储。然而,在实际应用中,多是获取数据后直接通过网络把数据发送出去。那么本文章将开始学习hi3516a获取数据后通过网线和RTP协议把数据实时发送出去。
背景:hi3516a开发板通过HDMI接口获取BT1120数据后进行压缩,并通过RTP协议进行实时的视频直播。
硬件平台:hi3516a
软件平台:Hi3516A_SDK_V1.0.5.0
视频数据接口:HDMI
源码解析
下面继续上一篇文章的源码分析,分析void EventLoop(int s32MainFd)函数。
void EventLoop(int s32MainFd)
{
static int s32ConCnt = 0;//已经连接的客户端数
int s32Fd = -1;
static RTSP_buffer *pRtspList=NULL;
RTSP_buffer *p=NULL;
unsigned int u32FdFound; //找到fd标识,找到就置1
/*接收连接,创建一个新的socket*/
if (s32ConCnt!=-1)
{
s32Fd= tcp_accept(s32MainFd);
}
/*处理新创建的连接*/
if (s32Fd >= 0)
{
/*查找列表中是否存在此连接的socket*/
for (u32FdFound=0,p=pRtspList; p!=NULL; p=p->next)
{
if (p->fd == s32Fd)
{
u32FdFound=1;
break;
}
}
if (!u32FdFound)
{
/*创建一个连接,增加一个客户端*/
if (s32ConCnt<MAX_CONNECTION) //#define MAX_CONNECTION 10/*rtsp connection*/
{
++s32ConCnt;
AddClient(&pRtspList,s32Fd); //在rtsp_buffer链表中新增一个链表
}
else
{
fprintf(stderr, "exceed the MAX client, ignore this connecting\n");
return;
}
num_conn++;
fprintf(stderr, "%s Connection reached: %d\n", __FUNCTION__, num_conn);
}
}
/*对已有的连接进行调度*/
ScheduleConnections(&pRtspList,&s32ConCnt);
}
上述主要有两个关键点,若链表中没有找到对应的连接,会新建一个连接并调用AddClient(&pRtspList,s32Fd); 在链表中新增一个链表,每个客户端的首次连接会调动该部分。
最后,调用ScheduleConnections(&pRtspList,&s32ConCnt)函数,这个函数主要对已有的连接进行调度。
void ScheduleConnections(RTSP_buffer **rtsp_list, int *conn_count)
{
int res;
RTSP_buffer *pRtsp=*rtsp_list,*pRtspN=NULL;
RTP_session *r=NULL, *t=NULL;
#ifdef RTSP_DEBUG
// fprintf(stderr, "%s\n", __FUNCTION__);
#endif
while (pRtsp!=NULL)
{
if ( (res = RtspServer(pRtsp))!=ERR_NOERROR )
{
if (res==ERR_CONNECTION_CLOSE || res==ERR_GENERIC)
{
/*连接已经关闭*/
if (res==ERR_CONNECTION_CLOSE)
fprintf(stderr,"fd:%d,RTSP connection closed by client.\n",pRtsp->fd);
else
fprintf(stderr,"fd:%d,RTSP connection closed by server.\n",pRtsp->fd);
/*客户端在发送TEARDOWN 之前就截断了连接,但是会话却没有被释放*/
if (pRtsp->session_list!=NULL)
{
r=pRtsp->session_list->rtp_session;
/*释放所有会话*/
while (r!=NULL)
{
t = r->next;
RtpDelete((unsigned int)(r->hndRtp));
schedule_remove(r->sched_id);
r=t;
}