比使用C ++中的OpenCV库更快地获取帧总数和FPS

时间:2018-07-20 16:48:44

标签: c++ opencv video ffmpeg

我需要检查哪些视频可以分析,哪些不能给出视频中的帧总数和视频的fps。我创建了一个c ++程序来进行检查。由于分析非常耗时,因此无法选择分析每个视频。

我使用了OpenCV库作为初学者:

    cv::VideoCapture vid_to_analyze;
    vid_to_analyze.open( me_vid.vid_path.string() );
    me_vid.total_frames= static_cast<int>(vid_to_analyze.get(CV_CAP_PROP_FRAME_COUNT));
    me_vid.fps=vid_to_analyze.get(CV_CAP_PROP_FPS);

    if (!vid_to_analyze.isOpened())
    {
        std::cout << "Skipping vid: "<< me_vid.vid_path.string()<<", couldn't open it" << std::endl;
    }
    if (me_vid.fps != me_vid.fps || me_vid.fps <= 0)
    {
        std::cout << "For video " << me_vid.vid_path.string() << std::endl;
        std::cout << "FPS of the video file cannot be determined, assuming 30"<< std::endl;
        me_vid.fps = 30;
    }

    vid_to_analyze.release();

但是,在调试时,它会变得非常缓慢(该程序在没有连接调试器的情况下运行速度更快,但是鉴于需要覆盖的视频数量,它仍然非常慢)。我认为这与每次打开(发布)视频时创建和删除4个线程有关。

如何以更快的方式获取帧总数和fps (无需实际创建4个线程!),如果我对从视频中实际获取帧不感兴趣的只是帧数和fps。

有没有一种方法可以使用c ++中的ffmpeg库,那会更快并且从哪里开始?

编辑:Valgrind似乎同意,因为{Ir =)vid_to_analyze.open阶段花费了91.66%的时间

1 个答案:

答案 0 :(得分:0)

视频的属性称为元数据

您可以通过限制视频文件格式来优化元数据的获取。

I / O是您花费时间的地方。 I / O的大部分时间都超出了程序的控制范围(留给OS和其他设备使用)。

以下是一些有关快速获取帧数的建议:
1.为文件格式的元数据分配内存。
2.阻止将元数据从文件中读取到内存中。
3.从元数据部分获取帧数。
前提是您的视频格式已预先计算了帧数。

否则,请尽最大努力保持I / O流:
1.读取视频数据,如果可能,读取多个帧。
2.计算缓冲区中的帧数。
3.重复#1。

您可以执行双缓冲和线程来加快速度:
1.“读取”线程将数据读取到缓冲区中。
   缓冲区已满后,它将读入另一个缓冲区。

  1. “处理中”线程在缓冲区中处理数据。
    处理线程可能要等待,直到有可用的缓冲区为止。

目标是提供足够的缓冲区,以使“读取”线程不会停止。 “正在处理”线程将在“正在读取”线程正在读取时进行帧计数。 (等待I / O操作完成时有足够的时间进行处理。)

此外,查看“内存映射文件”。这是操作系统将文件视为内存,并根据需要将文件的块加载到内存中的概念。