我有几个 Axis IP 摄像机,我想通过 RTP 将它们的 H264 输出流式传输到我的应用程序。到目前为止,大部分时间一切都在工作,通常使用一台相机。一旦我连接了多个摄像头,我在使用的每个 jrtplib 实例上都会收到很多丢失的数据包,从而导致视频质量不佳(伪影、损坏的图像等)。
因此,我创建了一个小型测试设置,仅连接一台相机并仅使用一个 jrtplib 实例,代码或多或少直接取自样本。
using namespace jrtplib;
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
RTPSession sess;
sessparams.SetOwnTimestampUnit(1.0 / 90000.0);
sessparams.SetAcceptOwnPackets(true);
transparams.SetPortbase(rtp_port);
auto status = sess.Create(sessparams, &transparams);
checkerror(status);
uint16_t last_sn = 0;
while (1)
{
sess.BeginDataAccess();
// check incoming packets
if (sess.GotoFirstSourceWithData())
{
do
{
RTPPacket *pack;
while ((pack = sess.GetNextPacket()) != NULL)
{
// You can examine the data here
auto sn = pack->GetSequenceNumber();
if (0!=last_sn && sn - last_sn != 1)
{
std::cout << "\tmissing packets: " << (sn - last_sn) << std::endl;
}
std::cout << sn << std::endl;
last_sn = sn;
// we don't longer need the packet, so
// we'll delete it
sess.DeletePacket(pack);
}
} while (sess.GotoNextSourceWithData());
}
sess.EndDataAccess();
status = sess.Poll();
checkerror(status);
Sleep(1);
}
sess.BYEDestroy(RTPTime(10, 0), 0, 0);
即使通过这个简单的测试,我得到了丢失的数据包(丢失的序列号),我还检查了丢失的序列号是否只是延迟了,但没有。
但是当我添加transparams.SetRTPReceiveBuffer
到一个相当高的值时,比如 1048576 字节,它会停止丢失数据包,至少对于这个示例是这样。
在我的真实世界代码中,增加接收缓冲区没有帮助。我还尝试将其session.Poll()
移至单独的线程。
使用 Wireshark 捕获 UDP 数据包显示没有丢弃数据包,所以它与 libjrtp 相关?有没有人有这方面的经验,或者甚至建议使用另一个图书馆?我在这一点上非常卡住......
感谢您的任何提示,也许这只是一个小问题,我只是没看到
问候