live555 中的例子testRTSPClient.cpp 提供了一个创建rtsp客户端接收视频流的例子,使用该例子可从支持rtsp协议的摄像机获取视频流。因为我用的相机提供的是h264编码的实时流,并且我希望在接收实时流的时候保存录像,因此对testRTSPClient.cpp进行了简单的修改。 continueAfterSETUP 函数中,进行如下修改:
- scs.subsession->sink=H264VideoFileSink::createNew(env,"test.h264",NULL,550000,false);
H264VideoFileSink继承了FileSink,实际上,每一帧视频都是在filesink中写入test.h264文件的。因此在filesink中进行处理。void FileSink::addData(unsigned char const* data, unsigned dataSize,struct timeval presentationTime) 函数的传入参数,unsigned char const* data, unsigned dataSize 分别是一帧的内容和一帧的长度(这个视频帧没有h264的开头0001,void H264VideoFileSink::afterGettingFrame 这个函数中有添加0001的 代码)。FileSink::addData 中获取的一帧视频(接收到的rtp包,有一个mark算一帧,因此NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)都是分开的)。关于如何判断帧类型,可以利用可以利用data[1]和0x1f进行位或运算。在用ffmpeg解码时,sps,pps和之后的idr帧是要一起传入解码器的,其他的sei我是直接丢弃,其实也可以sps+pps+sei+idr一起传入ffmpeg。先上一段代码,这段代码用于将需要解码的一帧存入一个缓存区中,之后ffmpeg 解码缓存区的数据。
进行如下定义: