PS:要转载请注明出处,本人版权所有。
PS: 这个只是基于《我自己》的理解,
如果和你的原则及想法相冲突,请谅解,勿喷。
前置说明
本文作为本人csdn blog的主站的备份。(BlogID=075)
本文发布于 2019-01-04 14:56:29,现用MarkDown+图床做备份更新。blog原图已丢失,使用csdn所存的图进行更新。(BlogID=075)
环境说明
无
背景
由于公司需要把相关视觉算法结果以流媒体的方式可视化出来,这样可以有利于推广、演示和其他等等。
一般来说:视觉算法一般都是通过某种方式(USB接口、RTSP等等方式)采集摄像头的图像数据,然后送入视觉算法,取出视觉算法的结果,然后根据算法结果在原图上画出相关的检测结果,这样即可把算法结果可视化,而且也是比较实际的一种可视化方式。
现在要做的是把这些可视化结果做成一个可以播放的视频。根据这样一个需求,初步确定就是视频编码然后通过相应的流媒体协议发送出去,然后就可以用相应的播放器播放了。由于考虑到后期可能会涉及到移动端播放视频以及以及减轻前端的开发难度(前端可直接用H5播放),选择了H264+RTMP这样一种方式。
市面上成熟的RTMP服务器很多,开源的也有(SRS,CRTMPSERVER等等),商业的也有(万恶之源ADOBE FLASH SERVER),它们的一般流程都是:一个程序推流,一个RTMP服务器接收推送的流。但是考虑到我们的嵌入式设备,要尽可能的减少资源占用,精简项目架构,准备把推流和RTMP服务器结合起来开发。
于是,需要在设备上采集相机数据(解码),送给视觉算法检测,然后把检测结果画出来,然后通过H264编码,然后其他人可以通过打开一个网页看到我们的RTMP服务器推送是视频。
H264编码
本系列的重点本来是根据RTMP协议实现一个RTMP服务器,至少我没有做这件事情之前是这样认为的。但是做完这件事情后,我发现还是先从一些和RTMP相关的H264的要点说起来。
H264的基本知识网上有许多资料,我这里不会完整的翻译这些文章,我只会提出部分内容,这些内容是和RTMP推流息息相关的。(PS:说一句,我在整个过程中用了许多H264相关的知识,但是我依然是一个H264的小白,我只需要会用就行了,至于怎么压缩怎么编码的,我根本不知道!!!!!!)
阅读本文前:建议先找一篇网上的有H264详细内容的看一看,了解个大概。
NALU
H264 的功能结构分为视频编码层(VCL)和网络提取层(NAL).VCL层输出的是编码器输出原始图像经过编码后的数据流,NAL层输出的是可以存储和传输的数据结构。
NAL = NALHeader + RBSP(Raw Byte Sequence Payload)
NALHeader有如下我们熟悉的内容:
0x65 ---- I帧NALHeader
0x67 ---- sps帧NALHeader,这里面包含了分辨率及其他解码器需要的信息。
0x68 ---- pps帧NALHeader,这里包含了解码器需要的信息。
... ...
RBSP就是实际携带视频数据的字段。
注意:这里的一个NALU可能一帧数据(一张图片)也可能不是。
Annex B ---- Byte stream format
在h264的文档中,附录B有一个字节流格式,这个是官方推荐和国际标准的。所以,现在大多数编码器输出的数据的结构变为了这种结构。结构如下:
STARTCODE + NALU = STARTCODE + NALHeader + RBSP
STARTCODE 就是 0x000001 或者 0x00000001
这种结构如官方文档下图所示:
后记
以上两类知识在RTMP是非常重要。
参考文献
- 无
PS: 请尊重原创,不喜勿喷。
PS: 要转载请注明出处,本人版权所有。
PS: 有问题请留言,看到后我会第一时间回复。