代码之家  ›  专栏  ›  技术社区  ›  rescdsk

不可靠的缓存和视频帧的预读

  •  2
  • rescdsk  · 技术社区  · 15 年前

    我正在开发一个同时显示多个视频的应用程序。视频以充满图像文件的目录的形式存储。对于每个帧编号,必须从磁盘加载最多9个图像。我想实现图像的缓存和预读。这很简单,但复杂的是文件系统(有时是网络FS)的速度远远不够快,无法显示每个图像。所以readahead应该选择它要尝试加载的帧,并且只对那些图像发出read()请求。此外,在决定要加载哪个帧时,最好能考虑到已经缓存了哪些图像。

    我想出了一个贪婪的算法,可以做的很好,但我想知道这是否是一个已经研究过的问题,还有更好的/最优的算法。

    我假设时间是以帧速率来衡量的,而不是以秒来衡量的,以使伪代码更容易实现。

    load_time_per_image = how long it takes to load an image
    images_per_frame = the number of images to display simultaneously
    worst_time = images_per_frame * load_time_per_image
    
    def decide_next_frame_to_load:
        for each frame from now to now + worst_time:
            loadable = (frame - now) / load_time_per_image
            if number_of_images_cached(frame) > images_per_frame - loadable:
                # this frame is the first one it's possible to load in time.
                return frame
    

    有人有建议吗? 谢谢你的帮助! -托马斯

    1 回复  |  直到 15 年前
        1
  •  0
  •   Rick C. Petty    15 年前

    这是否用于实时操作?

    我见过的一些性能最差的视频编辑器将通过将每个帧存储到自己的图像文件中来“索引”每个帧。你一直在使用这个存储机制吗?如果源视频已经存储为视频格式(每个文件一个),并且每个视频都有一个索引(基本上是每个帧的文件偏移量),那么效率会显著提高。然后,您可以使用操作系统的缓存机制来帮助提高性能。

    您可能还需要考虑的另一件事是以yuv格式存储图像,尽管它可能对联网的文件系统没有太大帮助。显示视频的应用程序可能运行得更快(部分原因是不需要进行从RGB到YUV的转换,而且通常是因为可以将YUV图像的绘制工作卸载到视频卡上),从而为文件系统的工作留出更多的时间。当我在X显示器上绘图时,我这样做只是为了避免抖动。

    至于缓存图像,我可能会使用一个单独的线程来尽可能快地从磁盘读取图像,而主线程会组装并显示图像。主线程可以每帧显示间隔执行一次循环,当缓冲/准备的图像量达到某个阈值时,单独的线程可以阻塞。像mplayer这样的视频播放器使用这种策略。