小编ksb*_*496的帖子

如何编码C++程序中生成的多个图像中的视频而不将单独的帧图像写入磁盘?

我正在编写C++代码,其中在执行其中实现的一些操作之后生成N个不同帧的序列.每个帧完成后,我将它作为IMG_%d.png写在磁盘上,最后我使用x264编解码器通过ffmpeg将它们编码为视频.

该程序主要部分的汇总伪代码如下:

std::vector<int> B(width*height*3);
for (i=0; i<N; i++)
{
  // void generateframe(std::vector<int> &, int)
  generateframe(B, i); // Returns different images for different i values.
  sprintf(s, "IMG_%d.png", i+1);
  WriteToDisk(B, s); // void WriteToDisk(std::vector<int>, char[])
}
Run Code Online (Sandbox Code Playgroud)

这种实现的问题是所需帧的数量N通常很高(N~100000)以及图像的分辨率(1920x1080),导致磁盘过载,产生数十GB的写入周期每次执行后.

为了避免这种情况,我一直试图找到关于将存储在向量B中的每个图像直接解析为编码器(如x264)的文档(无需将中间图像文件写入磁盘).虽然发现了一些有趣的话题,但没有一个能够专门解决我想要的内容,因为其中许多都涉及在磁盘上使用现有图像文件执行编码器,而其他人则提供其他编程语言(如Python)的解决方案(在这里你)可以为该平台找到一个完全令人满意的解决方案.

我想要获得的伪代码类似于:

std::vector<int> B(width*height*3);
video_file=open_video("Generated_Video.mp4", ...[encoder options]...);
for (i=0; i<N; i++)
{
  generateframe(B, i+1);
  add_frame(video_file, B);
}
video_file.close();
Run Code Online (Sandbox Code Playgroud)

根据我在相关主题上所读到的内容,x264 C++ API可能能够做到这一点,但是,如上所述,我没有找到满意的答案来解决我的具体问题.我尝试直接学习和使用ffmpeg源代码,但是它的低易用性和编译问题都迫使我放弃这种可能性,因为我只是一个非专业的程序员(我把它视为一种爱好而不幸的是我不能浪费很多时候学习如此苛刻的东西).

我想到的另一个可能的解决方案是找到一种方法在C++代码中调用ffmpeg二进制文件,并以某种方式设法将每次迭代的图像数据(存储在B中)传输到编码器,让每个帧的添加(即,不是"关闭"要写入的视频文件)直到最后一帧,以便可以添加更多帧直到到达第N个帧,其中视频文件将被"关闭".换句话说,通过C++程序调用ffmpeg.exe将第一帧写入视频,但让编码器"等待"更多帧.然后再次调用ffmpeg添加第二帧并使编码器再次"等待"以获得更多帧,依此类推,直到到达最后一帧,视频将完成.但是,我不知道如何进行或者实际上是否可行.

编辑1:

正如回复中所建议的那样,我一直在记录有关命名管道的信息,并尝试在我的代码中使用它们.首先,应该注意我正在使用Cygwin,所以我的命名管道是在Linux下创建的.我使用的修改过的伪代码(包括相应的系统库)如下:

FILE *fd;
mkfifo("myfifo", 0666);

for (i=0; i<N; i++)
{
  fd=fopen("myfifo", "wb");
  generateframe(B, i+1);
  WriteToPipe(B, fd); // void WriteToPipe(std::vector<int>, FILE …
Run Code Online (Sandbox Code Playgroud)

c++ video ffmpeg image x264

18
推荐指数
2
解决办法
1万
查看次数

标签 统计

c++ ×1

ffmpeg ×1

image ×1

video ×1

x264 ×1