Browse Source

Introduce opaque FFMPEG handler

rexim 2 years ago
parent
commit
e2bfcc5a61
3 changed files with 32 additions and 22 deletions
  1. 8 4
      ffmpeg.h
  2. 23 13
      ffmpeg_linux.c
  3. 1 5
      main_raw.c

+ 8 - 4
ffmpeg.h

@@ -3,9 +3,13 @@
 
 #include <stddef.h>
 
-int ffmpeg_start_rendering(size_t width, size_t height, size_t fps);
-void ffmpeg_send_frame(int pipe, void *data, size_t width, size_t height);
-void ffmpeg_send_frame_flipped(int pipe, void *data, size_t width, size_t height);
-void ffmpeg_end_rendering(int pipe);
+typedef void FFMPEG;
+
+FFMPEG *ffmpeg_start_rendering(size_t width, size_t height, size_t fps);
+// TODO: handle potential error that may happen in all of the ffmpeg function
+void ffmpeg_send_frame(FFMPEG *ffmpeg, void *data, size_t width, size_t height);
+// TODO: use -vflip of ffmpeg instead
+void ffmpeg_send_frame_flipped(FFMPEG *ffmpeg, void *data, size_t width, size_t height);
+void ffmpeg_end_rendering(FFMPEG *ffmpeg);
 
 #endif // FFMPEG_H_

+ 23 - 13
ffmpeg_linux.c

@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
 #include <errno.h>
@@ -11,25 +12,30 @@
 #define READ_END 0
 #define WRITE_END 1
 
-int ffmpeg_start_rendering(size_t width, size_t height, size_t fps)
+typedef struct {
+    int pid;
+    int pipe;
+} FFMPEG;
+
+FFMPEG *ffmpeg_start_rendering(size_t width, size_t height, size_t fps)
 {
     int pipefd[2];
 
     if (pipe(pipefd) < 0) {
         fprintf(stderr, "ERROR: could not create a pipe: %s\n", strerror(errno));
-        return -1;
+        return NULL;
     }
 
     pid_t child = fork();
     if (child < 0) {
         fprintf(stderr, "ERROR: could not fork a child: %s\n", strerror(errno));
-        return -1;
+        return NULL;
     }
 
     if (child == 0) {
         if (dup2(pipefd[READ_END], STDIN_FILENO) < 0) {
             fprintf(stderr, "ERROR: could not reopen read end of pipe as stdin: %s\n", strerror(errno));
-            return -1;
+            exit(1);
         }
         close(pipefd[WRITE_END]);
 
@@ -60,30 +66,34 @@ int ffmpeg_start_rendering(size_t width, size_t height, size_t fps)
         );
         if (ret < 0) {
             fprintf(stderr, "ERROR: could not run ffmpeg as a child process: %s\n", strerror(errno));
-            return -1;
+            exit(1);
         }
         assert(0 && "unreachable");
     }
 
     close(pipefd[READ_END]);
 
-    return pipefd[WRITE_END];
+    FFMPEG *ffmpeg = malloc(sizeof(FFMPEG));
+    assert(ffmpeg != NULL && "Buy MORE RAM lol!!");
+    ffmpeg->pid = child;
+    ffmpeg->pipe = pipefd[WRITE_END];
+    return ffmpeg;
 }
 
-void ffmpeg_end_rendering(int pipe)
+void ffmpeg_end_rendering(FFMPEG *ffmpeg)
 {
-    close(pipe);
-    wait(NULL);
+    close(ffmpeg->pipe);
+    waitpid(ffmpeg->pid, NULL, 0);
 }
 
-void ffmpeg_send_frame(int pipe, void *data, size_t width, size_t height)
+void ffmpeg_send_frame(FFMPEG *ffmpeg, void *data, size_t width, size_t height)
 {
-    write(pipe, data, sizeof(uint32_t)*width*height);
+    write(ffmpeg->pipe, data, sizeof(uint32_t)*width*height);
 }
 
-void ffmpeg_send_frame_flipped(int pipe, void *data, size_t width, size_t height)
+void ffmpeg_send_frame_flipped(FFMPEG *ffmpeg, void *data, size_t width, size_t height)
 {
     for (size_t y = height; y > 0; --y) {
-        write(pipe, (uint32_t*)data + (y - 1)*width, sizeof(uint32_t)*width);
+        write(ffmpeg->pipe, (uint32_t*)data + (y - 1)*width, sizeof(uint32_t)*width);
     }
 }

+ 1 - 5
main_raw.c

@@ -4,10 +4,6 @@
 #include <string.h>
 #include <errno.h>
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
 #define OLIVEC_IMPLEMENTATION
 #include "olive.c"
 
@@ -22,7 +18,7 @@ uint32_t pixels[WIDTH*HEIGHT];
 
 int main(void)
 {
-    int ffmpeg = ffmpeg_start_rendering(WIDTH, HEIGHT, FPS);
+    FFMPEG *ffmpeg = ffmpeg_start_rendering(WIDTH, HEIGHT, FPS);
 
     Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT, WIDTH);