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]: %d\n", child_pipe[0], child_pipe[1]);
args.ffmpeg = &(FFMpeg){.std_in = child_pipe[WRITE_END]};
child_pid = fork();
printf("child: %d\n", 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 ram\n");
return;
}
int ret = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888, pixels, image->width * sizeof(Uint32));
if (ret != 0) {
fprintf(stderr, "SDL_RenderReadPixels failed: %s\n", 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.
It was an extremely stupid issue. On this line
int n = write(ffmpeg->std_in, image->img_data, size);
I'm writing the image data instead of the data I get from SDL2