0

我正在开发一个多媒体应用程序,它使用 liveMedia 库通过 RTSP 流式传输视频和音频。我从相机读取原始视频帧,使用 libx264 对其进行编码,将其保存在 tbb::concurrent_queue 中并运行 RTSP 服务器。我使用 DynamicRTSPServer.cpp 和 live555MediaServer.cpp 作为示例来创建我的 RTSP 模块,但我遇到了一个问题 - 一个线程(执行 BasicTaskScheduler::doEventLoop )使用过多的处理器时间 - 超过 80-90% 的一个处理器内核(我有英特尔双核 T3100)。而对于我的视频流,我有很长的延迟,VLC 无法播放视频流(音频流播放正常)出现错误:主要警告:图片太迟无法显示(缺少 3780 毫秒)avcodec 错误:超过 5 秒迟到的视频->

我阅读了服务器的日志文件,发现我有很多失败的尝试从空队列中读取新数据。这是我的日志文件的片段(查看调试消息的时间 - 这是 FramedSource::doGetNextFrame 的不同调用)

[10:49:7:621]: videoframe readed. size:  0
[10:49:7:622]: videoframe readed. size:  0
[10:49:7:622]: videoframe readed. size:  0
[10:49:7:622]: videoframe readed. size:  0
[10:49:7:622]: videoframe readed. size:  0
[10:49:7:622]: videoframe readed. size:  0
[10:49:7:623]: videoframe readed. size:  0
[10:49:7:623]: videoframe readed. size:  0
[10:49:7:623]: videoframe readed. size:  0
[10:49:7:623]: videoframe readed. size:  0
[10:49:7:623]: videoframe readed. size:  0
[10:49:7:624]: videoframe readed. size:  0

我的视频流的帧率很低(相机只能达到 8 fps 或更低),当调用 doGetNextFrame 时,我的缓冲区在队列中还没有任何编码帧。在此尝试中,我有下一个调用堆栈:

ConcurrentQueueBuffer::doGetNextFrame()
FramedSource::getNextFrame(unsigned char* to, unsigned maxSize,
                                afterGettingFunc* afterGettingFunc,
                                void* afterGettingClientData,
                                onCloseFunc* onCloseFunc,
                                void* onCloseClientData)
StreamParser::ensureValidBytes1(unsigned numBytesNeeded)
StreamParser::ensureValidBytes(unsigned numBytesNeeded) 
StreamParser::test4Bytes()
H264VideoStreamParser::parse()
MPEGVideoStreamFramer::continueReadProcessing()
MPEGVideoStreamFramer::continueReadProcessing(void* clientData,
                         unsigned char* /*ptr*/, unsigned /*size*/,
                         struct timeval /*presentationTime*/)
StreamParser::afterGettingBytes1(unsigned numBytesRead, struct timeval presentationTime)
StreamParser::afterGettingBytes(void* clientData,
                                     unsigned numBytesRead,
                                     unsigned /*numTruncatedBytes*/,
                                     struct timeval presentationTime,
                                     unsigned /*durationInMicroseconds*/)
FramedSource::afterGetting(FramedSource* source)
AlarmHandler::handleTimeout()
...

当编码器给我新的帧时,我试图改变我的缓冲区和锁定线程的逻辑,但在这种情况下,我的音频流也有很长的延迟。我在服务器启动时设置了一些延迟,以便在缓冲区中保存更多数据,但是 livemedia 从缓冲区读取数据的速度比编码器编码要快:(

这个问题的原因是什么?liveMedia 如何检测从 FramedSource 读取的尝试频率?

我的 H264BufferMediaSubsession 继承了 liveMedia 的 H264VideoFileServerMediaSubsession 并仅覆盖 createNewStreamSource() 虚拟方法,我在其中创建 FramedSource 它将从我的缓冲区中读取数据。

4

0 回答 0