I made a small animation using SDL2 and I want to use ffmpeg to convert it to an h264 encoded video. I’m getting the texture RGBA pixels using SDL_RenderReadPixels
and sending them to ffmpeg for rendering. The video does render, but is all messed up. The following is my code
Spawning ffmpeg
int child_pipe[2];
if (pipe(child_pipe) < 0) {
perror("child_pipe");
}
printf("child_pipe[0]: %d, child_pipe[1]: %dn", child_pipe[0], child_pipe[1]);
args.ffmpeg = &(FFMpeg){.std_in = child_pipe[WRITE_END]};
child_pid = fork();
printf("child: %dn", child_pid);
if (child_pid == 0) {
close(child_pipe[WRITE_END]);
if (dup2(child_pipe[READ_END], STDIN_FILENO) < 0) {
perror("dup2");
return -1;
}
char *argv[] = {"ffmpeg", "-loglevel", "verbose", "-y", "-f", "rawvideo", "-pixel_format", "rgba", "-s",
"894x702", "-i", "-", "-c:v", "libx264", "-pix_fmt", "yuv420p", "thing.mp4", NULL};
int x = execvp("ffmpeg", argv);
if (x != 0) {
perror("execv");
return x;
}
return -1;
}
Here’s how I render into SDL2 renderer. The rendering on SDL2 has no issues. In here I get the render pixels and send them to ffmpeg.
void render_image(SDL_Renderer *renderer, int array[], size_t array_size, Image *image, FFMpeg *ffmpeg) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for (int i = 0; i < array_size; i++) {
paint_image_strip(renderer, image, i, array[i]);
}
if (ANIMATION_DELAY_MS > 0) {
SDL_Delay(ANIMATION_DELAY_MS);
}
if (ffmpeg != NULL) {
int size = image->width * image->height * sizeof(Uint32);
Uint32 *pixels = (Uint32 *)malloc(size);
if (pixels == NULL) {
printf("Malloc failed. Buy more ramn");
return;
}
int ret = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888, pixels, image->width * sizeof(Uint32));
if (ret != 0) {
fprintf(stderr, "SDL_RenderReadPixels failed: %sn", SDL_GetError());
free(pixels);
}
int n = write(ffmpeg->std_in, image->img_data, size);
if (n < 0) {
perror("write failed");
}
free(pixels);
}
SDL_RenderPresent(renderer);
}
Here’s the issue. Here is what I see in SDL2 window
and this is what ffmpeg renders
there are inklings of the original image here. I thought it was an issue with RGBA vs ARGB but on double checking that wasn’t the case.
Expecting proper ffmpeg rendering.