c++ - 比 C++ 中的 OpenCV 库更快地获取总帧数和 FPS
问题描述
我需要检查哪些视频可以分析,哪些不能给出视频中的总帧数和视频的 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 不感兴趣,如何以更快的方式获得总帧数和 fps (实际上不创建 4 个线程!!)。
有没有办法从 c++ 中使用 ffmpeg 库,那会更快吗?从哪里开始?
编辑:Valgrind 似乎同意,因为 (Ir=)91.66% 的时间花费在该vid_to_analyze.open
阶段
解决方案
视频的属性称为元数据。
您可以通过限制视频文件格式来优化元数据的获取。
I/O 是您花费时间的地方。大部分 I/O 时间超出了程序的控制(留给操作系统和其他设备)。
以下是一些快速获取帧数的建议:
1. 为文件格式的元数据分配内存。
2. 块从文件中读取元数据到你的内存中。
3. 从元数据部分获取帧数。
前提是您的视频格式已经预先计算了帧数。
否则,请尽量保持 I/O 流:
1. 读入视频数据,如果可能,多帧。
2. 统计缓冲区的帧数。
3. 重复 #1。
您可以执行双缓冲和线程来加快速度:
1. “读取”线程将数据读入缓冲区。
缓冲区满后,它会读入另一个缓冲区。
- “处理”线程处理缓冲区中的数据。
处理线程可能希望等待,直到有可用的缓冲区。
目标是提供足够的缓冲区,以便“读取”线程不会停止。“处理”线程将在“读取”线程正在读取时进行帧计数。(在等待 I/O 操作完成时有足够的时间进行处理。)
另外,查看“内存映射文件”。这是操作系统将文件视为内存的概念,必要时将文件块加载到内存中。
推荐阅读
- javascript - 如何将strapi中的图像上传到集合类型字段?
- spring-boot - 创建线程并将消息从 Camel 路由到微服务并返回
- rust - 如何在 Rust 中使用十六进制表示法指定浮点数文字?
- html - 移动 chrome 上的键盘与 CSS 混淆
- javascript - 复制时没有可见的文本框
- swift - 将物理实体添加到 SKTileMapNode 上的所有图块
- django - 如何以正确的格式在 HTML 页面中显示 jinja2 模板(j2 文件)?
- javascript - Amazon S3 获取错误:“NoSuchKey”但是密钥确实存在
- scala - 加入 sequense slick 3.3.0 中的每个元素
- java - Jackson json 只转换选定的字段和方法