HI3518E RTSP main函数分析

将HI3518E当作服务器,用RTSP打包H264数据可以在局域网内采用rtsp观看。
main.c源码:

 int main(void)
    {
    	int s32MainFd,temp;
    	struct timespec ts = { 2, 0 };
    	pthread_t id;
    	//分配环形缓冲区,总共32个,每个大小为size
    	ringmalloc(1280*720);
    	printf("RTSP server START\n");
    //设置服务器信息全局变量,设置内容保存在stPrefs结构体
    	PrefsInit();
    	printf("listen for client connecting...\n");
    	signal(SIGINT, IntHandl);
    	//创建、设置、绑定、监听套接字,并将套接字设为非阻塞模式
    	s32MainFd = tcp_listen(SERVER_RTSP_PORT_DEFAULT);
    	/*创建线程schedule_do:nanosleep(&ts, NULL)让出CPU,超时时间33333纳秒=33微秒到重新获得CPU。获得CPU时,在stop_schedule=0的情况下,循环
    ringgetringget(&ringinfo)来取得3518里的H264数据然后用sched[i].play_action=RtpSend函数发送出去*/
    	if (ScheduleInit() == ERR_FATAL)
    	{
    		fprintf(stderr,"Fatal: Can't start scheduler %s, %i \nServer is aborting.\n", __FILE__, __LINE__);
    		return 0;
    	}
    	//设置rtp端口值,前面tcp_listen参数是RTSP端口,与RTP端口不同
    	RTP_port_pool_init(RTP_DEFAULT_PORT);
    	//SAMPLE_VENC_1080P_CLASSIC与H264编码差不多,只不过不是保存在文件里,而是通过网络直接发送
    	//出去,里面有个线程去处理视频流,读视频流时也会休眠
    	// 4个线程:1.main:负责切换所有线程,nanosleep让出cpu,超时唤醒
    	// 2.schedule_do:服务器取视频数据发 送线程,nanosleep让出cpu,超时唤醒
    	// 3.SAMPLE_VENC_1080P_CLASSIC:h264编码线程,sleep(1)让出CPU,但超时唤醒又死循环sleep(1),基本上可以不考虑这个线程
    	// 4.SAMPLE_COMM_VENC_GetVencStreamProc:读取3518的H264数据并保存到环形缓冲区线程,select休眠,有数据或超时唤醒
    	pthread_create(&id,NULL,SAMPLE_VENC_1080P_CLASSIC,NULL);
    	while (!g_s32Quit)
    	{
    		nanosleep(&ts, NULL);//超时时间为ts,NULL表示不记录剩余时间
    		EventLoop(s32MainFd);//这个s32MainFd是由上面的tcp_listen创建且是无阻塞模式
    	}
    	sleep(2);
    	ringfree();
    	printf("The Server quit!\n");
     
    	return 0;
    }

先从大框架解释一下,HI3518E编码产生数据,然后又通过RTSP将数据打包发送出去,很符合生产者消费者模式,所以我们定义了一个环形缓冲区ringmalloc(1280*720);PrefsInit()规定了RTSP的端口为554端口,tcp_listen()按linux网络编程流程函数创建、绑定了套接字然后监听端口,而且还设置了套接字是无阻塞模式。

纵观整个程序,总共4个线程,main主线程:nanosleep(&ts, NULL)让出CPU,超时时间2秒唤醒,不断在EventLoop()函数里进行检查是否有RTSP连接请求,清理断开的连接和会话,用多路IO复用select函数来查询是否有RTSP包生成,调用select休眠,有RTSP数据或超时100ms唤醒.有RTSP包时,读取接收到的包和客户端IP地址,并将这些内容保存到rtsp结构体里,然后根据rtsp结构体内容进行解析通信。

schedule_do线程:nanosleep(&ts, NULL)让出CPU,超时时间33333纳秒=33微秒到重新获得CPU。获得CPU时,在stop_schedule=0的情况下,循环ringgetringget(&ringinfo)来取得3518里的H264数据然后用sched[i].play_action=RtpSend函数发送出去。

SAMPLE_VENC_1080P_CLASSIC线程:sleep(1)让出CPU,但超时唤醒又循环sleep(1),基本上可以不考虑这个线程。HI3518E对H264编码前作一些初始化的准备工作,主要工作内容见前面博客:海思3518E H264编码然后创建线程SAMPLE_COMM_VENC_GetVencStreamProc。

SAMPLE_COMM_VENC_GetVencStreamProc线程:select休眠,有数据或超时唤醒。Hi3518E进行H264编码并将编码数据存到ringinfo里。

总的来说,这个项目其实是多线程的经典问题——生产者消费者模式的应用,注意线程的切换及无阻塞,一个线程监控新的连接,一个线程产生视频数据作为生产者,已握手成功的连接不断读取视频数据发送出去,这种线程作为消费者。能正确理解这三个线程立刻这个代码基本上没什么问题,至于RTSP协议以及怎么将H264数据打包成RTSP包发送出去以后再分析。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值