SDL2 C++ 捕获渲染器的视频 Animation/Sprite

SDL2 C++ Capturing Video of Renderer Animation/Sprite

我有一个使用 SDL2 创建的 animation/sprite。将动画渲染到屏幕时效果很好。但是现在我也想把它录制成一个视频文件(本地存储)。为此,我计划使用 FFmpeg API,我将向其发送原始 RGB 像素数据数组。

我的问题是从 SDL2 API 获取数据。

我试过的是:

// From 
SDL_Surface *sshot = SDL_CreateRGBSurface(0, 750, 750, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_RenderReadPixels(gRenderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);

// From https://wiki.libsdl.org/SDL_RWFromMem
char fName[50];
sprintf(fName, "/tmp/a/ss%03d.bmp", fileCnt);


char bitmap[310000];
SDL_RWops *rw = SDL_RWFromMem(bitmap, sizeof(bitmap));
SDL_SaveBMP_RW(sshot, rw, 1); 

以上无效。但是使用以下代码将单个帧转储到文件中是可行的:

SDL_SaveBMP(sshot, "/tmp/alok1/ss.bmp")

这显然不是一个可接受的解决方案 - 写入数千个 BMP,然后从命令行使用 FFmpeg 创建视频。

我做错了什么?您如何从 SDL_RWops? Is the use of SDL_RWFromMem 正确处理我的问题陈述的方法中提取数据?

您的缓冲区太小,无法容纳指定的图像,因此无法保存在此处。将缓冲区大小至少增加到实际图像大小 + BMP header(width*height*bpp + 54,但也需要计算填充(SDL_Surface 指的是 pitch))。

请注意,从堆栈中取出 3Mb 可能会使您危险地接近溢出(但仍然可以,取决于在相关函数之前的函数中发生的情况)。 Chain-calling 几个占用大量堆栈的函数可能会很快耗尽它。您可能根本不需要任何额外的 space 或 BMP 转换 - 例如创建 AVImage 并将像素直接从 SDL_Surface.

复制到它

同样在性能方面,这种回读也不会很好(但无论如何压缩本身可能要重得多)。