项目记录-”海迪康”ipcamera客户端开发纪实

一开始拿到IPcamera是为了在预警系统中加入一个摄像头,正好老师带来了一个IPcamera,但是并没有说明书和文档,一开始听到这个名字还以为只要知道了这个IP地址就可以为所欲为了,OK,NO,拿到了地址也并不知道怎么操纵,上网搜了一下“海迪康”这个牌子,搜到了做监控的大厂的海康威视的论坛,里面有海康摄像头的开发者说明书,下了一个ActiveX插件,很迷,改了UID和密码试了一下竟然成功连上。这时候不知道原理,只是把他嵌入到我们的网页中,匆匆实现了一下这部分功能。

然后开始跟熊大研究如何了解这个摄像头的原理,利用wireshark抓到了“官方”客户端与摄像头通信的包。(第一次感受到wireshark的强大)

拿到了通信的数据包,各种猜,我们得出了初步的解析。

前提条件:摄像头,电脑连接到同一局域网

交互流程:

               项目记录-”海迪康”ipcamera客户端开发纪实_第1张图片

2017进展:将摄像头获取到的h264裸流整理保存成264文件,利用ffplay、爱奇艺万能播放器等可以播放

思路:将收到的裸流利用ffmpeg实时编码成yuv数据,利用SDL、OpenGL、Direct3D等底层视频播放技术对YUV数据进行播放

需要解决的问题:首先ffmpeg的例子针对视频的解码都是以文件为对象的,也就是说无法实时进行解码,想要解码一定要先保存成文件再进行解码操作,看了ffmpeg源码,他的内部是逐帧进行操作的,但是想要灵活运用ffmpeg源码还是有难度的,不知道ffmpeg有关的函数,而且底层播放技术也不熟悉,这是个问题!下一步是学习ffmpeg的解码处理过程以及其中用到的函数。

2018进展:利用回调方法实现了ffmpeg解码+SDL实时播放的功能,但有明显卡顿和延迟

过程:在找到ffmpeg回调方法之后,尝试了利用文件作为缓冲“实时”播放视频,将视频循环存储到9个文件中,程序依次读取文件并进行播放,第一次在实时播放上有了进展,但是毕竟存和读不能同时进行,所以势必会有延迟,而且打开文件的间隙会卡顿。于是在雷神的博客中找到了内存中取数据解码利用回调函数进行解码播放。

https://blog.csdn.net/leixiaohua1020/article/details/12980423

在做这个的过程中还加深理解了传递指针的意义。

回调函数方法的核心是编写read_packet()函数,这个函数是主要是AVIOContext结构体需要,作为解码的数据来源使用,一旦解码需要更多数据,便调用此函数。

我设置了一个缓冲区,一个10000*9字节的数组,接受线程将接收到的h264裸流存到数组中,解码播放线程利用read_packet()函数读取数组中的数据,基本上实现了功能

缺点:卡顿,延迟,失真

我发现用这个方法时,由于ffmpeg解码需要流来判断文件格式,判断帧类型,判断关于视频的各种参数,而且经常需求>供给,按理说如果是解码速度快与接收速度的话视频应该不会卡,但是视频经常卡,所以猜测有可能是它要收到一定量的码流数才开始解析,而大小远超过真实的一帧的长度,或者有可能有一些码流没有完整解析所以造成了卡顿。

优化方法:

1.调节read_packet()读取的buffer长度

2.优化read_packet()中buf的赋值方法

最新进展:利用 av_parser_parse2() 函数进行逐帧解码,不用回调方法,延迟少于1秒,不卡顿,秒开屏。

果然之前卡顿大部分原因是时间损失到函数调用上,加上这次直接指定视频格式和窗口大小,不需要找解码器,解码流程速度加快。

经过后来的学习发现,问题应该是在解码参数的设置上,我并没有设置解码参数,比如B帧的存在,帧的延迟输出。

你可能感兴趣的:(ffmpeg)