视频监控客户端开发(IP Camera)总结
做了将近三年时间的视频监控客户端开发,当然期间也做个一些其他开发。在开发期间,经对系统不断进行重构优化积累了一些经验,现向大家分享一下。希望以此抛砖引玉,有这方面经验的朋友也发表一下看法和见解:
首先看下项目需求:
1.最多同时支持16路音视频同时显示。
2.窗口模式,全屏,1窗口,4窗口,9窗口,16窗口。
3.播放控制,开始播放,停止播放,开启音频,停止音频,云台控制,Camera管理。
下面谈谈设计方案:
1.总体设计,按照码流数据流向,可以将系统分成三层:
网络层,负责码流的接收,数据的解包,以及网络故障的处理。
解码显示层,网络层将数据解包后提交给解码层,解码层负责码流解码和图像显示。
UI层,负责响应消息并进行处理。
处理原则:层与层之间尽量独立,比如网络层发现网络故障后,进行以下处理:
1.通知UI网络故障。
2.自行进行网络重连。
3.故障恢复后通往UI层网络故障恢复。
期间并不需要通知解码显示层暂停解码显示。解码显示层收不到网络层提交的码流,自然会暂停解码
1.线程模型
先前的时候我的实现方式是,针对每一个播放窗口开一个线程,在这个线程中进行码流接收,然后进行解码显示。后来发现有诸多问题,其中最严重的就是解码耗时过长导致发送端经常出现发送超时的情形。
现在的实现方式是针对以上各层实现三类线程:
网络数据接收线程:负责网络数据接收,网络连接建立。由于最大只有16路码流数据,使用select进行多路复用足够满足我的需求。网络层还负责对码流数据进行解包和校验,测试证明进行数据解包和校验并不影响网络层的数据接收实时性。
解码显示线程:负责数据的解码和显示,开始我分别使用Semaphore和Event进行线程同步,这样造成了诸多不便,首先程序退出时需要SetEvent唤醒解码线程,暂停和开始播放也需要进行特殊处理,后来我采用最简洁明了的方式:用一个Sleep(1)解决了诸多同步上的问题。
while(!bExit)
{
if(bPlay)
{
if(有数据)
解码显示一帧数据;
else
Sleep(1);
}
}
UI线程,主要负责消息响应,UI线程在任何时候都不能阻塞,比如登陆操作直接提交给网络层,网络层收到登陆响应后再通知UI。
2.数据模型
网络层收到数据经解码后得到一帧一帧数据,由于每帧数据长度非常大(I帧比P帧长的多),定义一个固定长度的缓冲区存放一帧数据不是很好的做法。使用链表则会不断的分配和释放内存,造成内存碎片。使用循环缓冲区会增加一次数据拷贝。为此我对循环缓冲区进行扩展:
每次写入一帧数据,写入一帧数据之前先写入该帧数据的长度。
如果到了缓冲区的末尾,无法容纳一帧完整的数据,直接跳到缓冲区的开始位置写入数据。当然需要进行一些特殊处理。
3.其他方面:
使用Directshow框架可以方便解码显示,Directshow采用DirectDraw进行图像显示,效率有明显的提升。
Directshow的窗口模式比无窗口模式要容易控制,比如针对某个窗口进行显示和隐藏。
全屏播放的最好方法是:先将窗口最大化,置顶,然后隐藏窗口的标题栏,边框,窗口上的其他控件,取消全屏进行逆操作即可。
4.实现难点
我觉得最难得是音视频同步,因为接收的是实时码流,对时延要求较高,不能使用较大的缓冲,所以造成诸多问题,解决这些问题发了我相当大一部分时间,这个留作下回再做讨论吧。
大家有问题可以回复该帖,我会尽力答复。
首先看下项目需求:
1.最多同时支持16路音视频同时显示。
2.窗口模式,全屏,1窗口,4窗口,9窗口,16窗口。
3.播放控制,开始播放,停止播放,开启音频,停止音频,云台控制,Camera管理。
下面谈谈设计方案:
1.总体设计,按照码流数据流向,可以将系统分成三层:
网络层,负责码流的接收,数据的解包,以及网络故障的处理。
解码显示层,网络层将数据解包后提交给解码层,解码层负责码流解码和图像显示。
UI层,负责响应消息并进行处理。
处理原则:层与层之间尽量独立,比如网络层发现网络故障后,进行以下处理:
1.通知UI网络故障。
2.自行进行网络重连。
3.故障恢复后通往UI层网络故障恢复。
期间并不需要通知解码显示层暂停解码显示。解码显示层收不到网络层提交的码流,自然会暂停解码
1.线程模型
先前的时候我的实现方式是,针对每一个播放窗口开一个线程,在这个线程中进行码流接收,然后进行解码显示。后来发现有诸多问题,其中最严重的就是解码耗时过长导致发送端经常出现发送超时的情形。
现在的实现方式是针对以上各层实现三类线程:
网络数据接收线程:负责网络数据接收,网络连接建立。由于最大只有16路码流数据,使用select进行多路复用足够满足我的需求。网络层还负责对码流数据进行解包和校验,测试证明进行数据解包和校验并不影响网络层的数据接收实时性。
解码显示线程:负责数据的解码和显示,开始我分别使用Semaphore和Event进行线程同步,这样造成了诸多不便,首先程序退出时需要SetEvent唤醒解码线程,暂停和开始播放也需要进行特殊处理,后来我采用最简洁明了的方式:用一个Sleep(1)解决了诸多同步上的问题。
while(!bExit)
{
if(bPlay)
{
if(有数据)
解码显示一帧数据;
else
Sleep(1);
}
}
UI线程,主要负责消息响应,UI线程在任何时候都不能阻塞,比如登陆操作直接提交给网络层,网络层收到登陆响应后再通知UI。
2.数据模型
网络层收到数据经解码后得到一帧一帧数据,由于每帧数据长度非常大(I帧比P帧长的多),定义一个固定长度的缓冲区存放一帧数据不是很好的做法。使用链表则会不断的分配和释放内存,造成内存碎片。使用循环缓冲区会增加一次数据拷贝。为此我对循环缓冲区进行扩展:
每次写入一帧数据,写入一帧数据之前先写入该帧数据的长度。
如果到了缓冲区的末尾,无法容纳一帧完整的数据,直接跳到缓冲区的开始位置写入数据。当然需要进行一些特殊处理。
3.其他方面:
使用Directshow框架可以方便解码显示,Directshow采用DirectDraw进行图像显示,效率有明显的提升。
Directshow的窗口模式比无窗口模式要容易控制,比如针对某个窗口进行显示和隐藏。
全屏播放的最好方法是:先将窗口最大化,置顶,然后隐藏窗口的标题栏,边框,窗口上的其他控件,取消全屏进行逆操作即可。
4.实现难点
我觉得最难得是音视频同步,因为接收的是实时码流,对时延要求较高,不能使用较大的缓冲,所以造成诸多问题,解决这些问题发了我相当大一部分时间,这个留作下回再做讨论吧。
大家有问题可以回复该帖,我会尽力答复。
...全文
相关推荐
手机视频监控
**客户端访问**:在电脑端,使用浏览器或其他支持MJPEG或H.264播放的工具,输入手机的IP地址和端口号来访问实时视频流。
如何将手机转变为IP Camera:实用指南
在本章中,我们将探讨一个技术现象,即智能手机如何通过特定应用转变为网络摄像头,这种转变不仅为用户提供了便利,还开启了多样化应用场景的大门。我们还将审视这一技术背后的基本原理,以及它如何与现代通信技术相结合。当配置IP Camera应用时,手机可以使用多种网络连接方式以确保摄像头的数据能够传输到需要的地方。其中,Wi-Fi是最常用的方式之一,因为它不仅提供了快速的连接速度,还能通过家庭或办公网络进行数据传输。移动数据连接提供了一个便捷的解决方案,特别是在没有Wi-Fi覆盖的区域。
兼容onvif协议的电脑客户端
标签中的“ipc客户端”表明这是一个用于IP摄像机(IPC,Internet Protocol Camera)的客户端软件。IP摄像机是基于网络的视频监控设备,可以通过IP网络传输视频数据。
ip camera 流媒体转发服务器代码(windows版)
对于想要开发自己的视频监控系统或者需要处理大量视频流的项目,这样的代码资源非常有价值。同时,它也提供了优化和定制的可能性,以适应特定的业务需求。
手机实时视频监控
**视频捕获**:Android提供了Camera API(旧版)和Camera2 API(新版)来访问和控制设备的摄像头。开发者需要设置摄像头参数,如分辨率、帧率,然后启动预览并捕获视频帧。2.


进程/线程/DLL
