我正在研究一种算法,该算法需要在可能很长的视频中对视频帧进行非常快速的随机访问(最少30分钟)。我目前正在使用OpenCV的VideoCapture来阅读我的视频,但是搜索功能要么已经破解,要么非常慢。我到目前为止发现的最好的是在MKV容器内使用MJPEG编解码器,但速度不够快。
我可以选择任何视频格式,甚至可以创建一个新的视频格式。存储空间不是问题(当然在某种程度上)。唯一的要求是尽可能快地到视频中的任何位置寻找时间。理想情况下,我希望能够同时访问多个帧,充分利用我的四核CPU。
我知道关系数据库非常适合存储大量数据,它们允许同时读取访问,并且在使用索引时它们非常快。
SQLite是否适合我的特定需求?我计划存储以JPEG格式压缩的每个视频帧,并使用帧号索引快速访问它们。
编辑:对我来说,帧只是一张图片,而不是整个视频。一个30米的视频@ 25 fps包含30 * 60 * 25 = 45000帧,我希望能够使用它的号码快速获得其中一个。
编辑:对于那些可能感兴趣的人,我最终实现了一个自定义视频容器,将每个帧保存在固定大小的块中(因此,可以直接计算任何帧的位置!)。使用turbojpeg库压缩图像,文件访问是多线程的(对NCQ友好)。瓶颈不再是硬盘驱动器了,我终于获得了更好的性能:)
答案 0 :(得分:4)
我不认为使用SQLite(或任何其他dabatase引擎)是一个很好的解决方案。数据库不是文件系统。
如果您需要非常快速的随机访问,那么坚持使用文件系统,设计用于此类用法,并在此基础上进行了优化。根据你的评论,你说一个5小时的视频需要450k文件,嗯,这在我看来不是问题。当然,目录列表会有点长,但您将获得绝对最快可能的随机访问。并且它肯定比SQLite更快,因为你是一个抽象层次。
如果您真的担心目录列表时间,您只需要像树一样组织文件夹结构。这将为您提供更长的路径,但快速上市。
答案 1 :(得分:1)
保持高水平的视角。问题是OpenCV在源视频中的搜索速度不够快。这可能是因为
您的计算机有许多专用图形硬件可供使用,但它没有专门的功能来随机搜索17 GB数据集,无论是文件,数据库还是一组文件。每次搜索磁盘将花费几毫秒。对于SSD来说会更好,但仍然不是那么好。然后等待它加载到主存储器中你必须首先生成所有数据。
使用ffmpeg,它可以非常有效地处理解码,甚至可能使用GPU。这是一个tutorial。 (免责声明,我自己没有使用它。)
您可以预处理视频以添加关键帧。原则上,这不应该要求完全重新编码,至少对于MPEG,但我不太了解具体细节。 MJPEG实际上将所有帧都转换为关键帧,但你可以找到一个中间点,并且可能以2倍的大小成本寻求1.5倍的速度。但是要避免撞到磁盘。
至于SQLite,这是一个很好的解决方案,可以在17 GB的数据范围内寻找。数据库未针对随机访问进行优化的概念是poppycock。他们当然是。文件系统是一种数据库。由于硬件而非软件,17 GB的随机访问速度很慢。
我建议不要将文件系统用于此任务,因为它是与机器其余部分同步的共享资源。此外,创建50万个文件(并在完成后删除它们)将花费很长时间。那是不文件系统专门用于什么。但是,您可以通过将多个图像存储到每个文件来解决这个问题。但是,你需要一些格式来找到所需的图像,然后为什么不将它们全部放在一个文件中?
确实,(如果采用17 GB路由)为什么不忽略整个问题并将所有内容放入虚拟内存? VM在将磁盘搜索作为SQLite或文件系统方面同样出色。只要操作系统知道进程可以使用那么多内存,并且你使用的是64位指针,它应该是一个很好的解决方案,并且首先要尝试。