我有一个应用程序连接到RTSP摄像头并处理一些视频帧。根据相机分辨率和帧速率,我不需要处理所有帧,有时我的处理需要一段时间。我设计了一些东西,以便在读取框架时,将其传递给工作队列以供另一个线程处理。但是,根据系统负载/分辨率/帧速率/网络/文件系统/等,我偶尔会发现程序无法跟上摄像机的情况。
我发现用ffmpeg(我在10月中旬使用最新的git drop并在Windows上运行),落后几秒就可以了,你继续得到下一帧,下一帧,然而,一旦你得到,比你ffmpeg从ffmpeg获得的框架落后15-20秒偶尔会有腐败。也就是说,作为下一帧返回的内容通常会出现图形毛刺(帧底部的条纹等)。
我想做的是以某种方式检查我是否在实时流后面超过X帧,如果是,请清除缓存帧并开始获取最新/当前帧。
我的帧缓冲区读取线程(C ++)的当前片段:
while(runThread)
{
av_init_packet(&(newPacket));
int errorCheck = av_read_frame(context, &(newPacket));
if (errorCheck < 0)
{
// error
}
else
{
int frameFinished = 0;
int decodeCode = avcodec_decode_video2(ccontext, actualFrame, &frameFinished, &newPacket);
if (decodeCode <0)
{
// error
}
else
if (decodeCode == 0)
{
// no frame could be decompressed / decoded / etc
}
else
if ((decodeCode > 0) && (frameFinished))
{
// do my processing / copy the frame off for later processing / etc
}
else
{
// decoded some data, but frame was not finished...
// Save data and reconstitute the pieces somehow??
// Given that we free the packet, I doubt there is any way to use this partial information
}
av_free_packet(&(newPacket));
}
}
我已经google了并查看了ffmpeg文档中的某些功能,我可以调用它来刷新内容并使我能够赶上但我似乎找不到任何东西。如果您只想偶尔监视视频源(例如,如果您只想每秒或每分钟捕获一帧),则需要这种类型的解决方案。我唯一能想到的就是断开相机并重新连接。但是,我仍然需要一种方法来检测我收到的帧是否旧。
理想情况下,我能够做到这样的事情:
while(runThread)
{
av_init_packet(&(newPacket));
// Not a real function, but I'd like to do something like this
if (av_check_frame_buffer_size(context) > 30_frames)
{
// flush frame buffer.
av_frame_buffer_flush(context);
}
int errorCheck = av_read_frame(context, &(newPacket));
...
}
}