最近有个小伙伴需要实现一个RTSP客户端,那么最简单的方法无疑就是用live555。可是引入时碰到了各种问题,于是找我帮忙,我来研究了一下。将中间遇到的问题一一记录。

1 初次编译

因为偷懒,就直接用vcpkg进行编译。

vcpkg install live555

发现编译不过,错误原因为std::atomic_flag不认识,遂百度,看到一篇文章,只要增加宏禁用STL即可。

由于vcpkg编译时是依赖CMake的,于是我就想在CMake的时候指定NO_STD_LIB

vcpkg edit live555

在打开的VSCode中,修改CMakeLists.txt,增加definitions即可

……
if (WIN32)
    add_definitions(-DNO_GETIFADDRS)
endif(WIN32)
#从这里开始加
add_definitions(-DNO_STD_LIB)

改完以后就可以编译通过了(看文章的童鞋请不要急着执行这步,看完全文最后再做)

vcpkg install --no-downloads --editable live555

2 测试DEMO

编译通过以后,可以看下源码目录下的testProgs/testRTSPClient.cpp,直接拿他建个工程就可以跑起来。

如果希望存流,稍作修改,即可存储到需要的视频码流、

  • 如果不要音频,最好的方法是不要订阅,这里不展开描述了
  • 视频是按NAL回调的,如果想关注一帧齐了,关注fSubsession.rtpSource() 是否是Marker位即可。
  • 也可以看我之前的文章live555+VS2013编译
void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
				  struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {

  if (strcmp(fSubsession.mediumName(),"video") == 0)
  {
	  FILE* fd = fopen("./test.264", "ab");
	  if (fd)
	  {
		  char szHead[4] = { 0x00,0x00,0x00,0x01 };
		  fwrite(szHead, sizeof(szHead), 1, fd);
		  fwrite(fReceiveBuffer, frameSize, 1, fd);
		  fflush(fd);
		  fclose(fd);
	  }
  }
  
  
  // Then continue, to request the next frame of data:
  continuePlaying();
}

跑起来发现,I帧永远收不齐,很奇怪。
切换编码为多SLICE后,出现I帧部分NAL收齐,后续的NAL无法收到的情况。

3 解决I帧无法收齐问题

于是打断点进行了跟踪,发现单SLICE情况下,当I帧的那个NAL收到60多K后,RTP序号出现跳跃。
我们的RTSP是走的RTP over UDP的方案,且发送端未做平滑发送。因此怀疑是接收端缓冲区太小,I帧较大导致。

找到liveMedia/MultiFramedRTPSource.cpp。

MultiFramedRTPSource
::MultiFramedRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
		       unsigned char rtpPayloadFormat,
		       unsigned rtpTimestampFrequency,
		       BufferedPacketFactory* packetFactory)
  : RTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency) {
  reset();
  fReorderingBuffer = new ReorderingPacketBuffer(packetFactory);

  // Try to use a big receive buffer for RTP:
  increaseReceiveBufferTo(env, RTPgs->socketNum(), 50*1024);
}

发现了要点,默认只分配了50k缓存,加大到512k

  increaseReceiveBufferTo(env, RTPgs->socketNum(), 512*1024);

修改完成后重新编译live555,再次运行,OK

#前面如果没有编译,就可以不用做remove了
vcpkg remove live555
vcpkg install --no-downloads --editable live555

4 后记

实际上小伙伴是使用的VS2010,拿我这份live555去自行编译了。vcpkg的好处在于能够带上CMake,大大简化编译过程。

GitHub 加速计划 / vc / vcpkg
22.52 K
6.21 K
下载
vcpkg - 一个用于管理 C 和 C++ 库的工具,支持在 Windows、Linux 和 macOS 上安装和集成各种库。
最近提交(Master分支:1 个月前 )
4f746bc6 5 天前
6e90218d 5 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐