我正在开发一个多媒体应用程序,它使用liveMedia库通过RTSP传输视频和音频。 我从相机读取原始视频帧,使用libx264对其进行编码,将其保存在tbb :: concurrent_queue中并运行RTSP服务器。我使用DynamicRTSPServer.cpp和live555MediaServer.cpp作为创建我的RTSP模块的例子,我遇到了问题 - 一个线程(执行BasicTaskScheduler :: doEventLoop)使用了太多的处理器时间 - 超过80-90%的一个处理器核心(我有英特尔双核T3100)。 对于我的视频流,我有一个很长的延迟,VLC无法播放视频流(音频流正常播放),但有错误: 主要警告:图片太晚无法显示(缺少3780毫秒) avcodec错误:晚期视频超过5秒 - >丢帧(电脑太慢?) 当我禁用音频子会话时,我也有很高的CPU使用率,但VLC可以正常播放视频流。
我读取了服务器的日志文件,发现我从空队列中读取新数据的尝试失败很多。 这是我的日志文件的片段(查看调试消息的时间 - 它是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,它将从我的缓冲区中读取数据。