blind-to-video.c - blind - suckless command-line video editing utility
 (HTM) git clone git://git.suckless.org/blind
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       blind-to-video.c (3463B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #ifndef TYPE
            3 #include "common.h"
            4 
            5 USAGE("[-d] frame-rate ffmpeg-arguments ...")
            6 
            7 static int draft = 0;
            8 static int fd;
            9 
           10 #define FILE "blind-to-video.c"
           11 #include "define-functions.h"
           12 
           13 int
           14 main(int argc, char *argv[])
           15 {
           16         struct stream stream;
           17         char geometry[2 * INTSTRLEN(size_t) + 2];
           18         char *frame_rate;
           19         const char **cmd;
           20         size_t n = 0;
           21         int status, pipe_rw[2];
           22         pid_t pid;
           23         void (*process)(struct stream *stream, size_t n);
           24 
           25         ARGBEGIN {
           26         case 'd':
           27                 draft = 1;
           28                 break;
           29         default:
           30                 usage();
           31         } ARGEND;
           32 
           33         if (argc < 2)
           34                 usage();
           35 
           36         frame_rate = *argv++, argc--;
           37         cmd = ecalloc((size_t)argc + 12, sizeof(*cmd));
           38         cmd[n++] = "ffmpeg";
           39         cmd[n++] = "-f",       cmd[n++] = "rawvideo";
           40         cmd[n++] = "-pix_fmt", cmd[n++] = "ayuv64le";
           41         cmd[n++] = "-r",       cmd[n++] = frame_rate;
           42         cmd[n++] = "-s:v",     cmd[n++] = geometry;
           43         cmd[n++] = "-i",       cmd[n++] = "-";
           44         memcpy(cmd + n, argv, (size_t)argc * sizeof(*cmd));
           45 
           46         eopen_stream(&stream, NULL);
           47 
           48         sprintf(geometry, "%zux%zu", stream.width, stream.height);
           49 
           50         if (!strcmp(stream.pixfmt, "xyza"))
           51                 process = process_lf;
           52         else if (!strcmp(stream.pixfmt, "xyza f"))
           53                 process = process_f;
           54         else if (!strcmp(stream.pixfmt, "raw0"))
           55                 process = NULL;
           56         else
           57                 eprintf("pixel format %s is not supported, try converting to "
           58                         "raw0 or xyza with blind-convert\n", stream.pixfmt);
           59 
           60         epipe(pipe_rw);
           61         pid = efork();
           62 
           63         if (!pid) {
           64                 pdeath(SIGKILL);
           65                 close(pipe_rw[1]);
           66                 edup2(pipe_rw[0], STDIN_FILENO);
           67                 close(pipe_rw[0]);
           68                 eexecvp("ffmpeg", (char **)(void *)cmd);
           69         }
           70 
           71         free(cmd);
           72 
           73         close(pipe_rw[0]);
           74         fd = pipe_rw[1];
           75         if (process)
           76                 process_stream(&stream, process);
           77         else
           78                 esend_stream(&stream, fd, "<subprocess>");
           79         close(fd);
           80 
           81         ewaitpid(pid, &status, 0);
           82         return !!status;
           83 }
           84 
           85 #else
           86 
           87 static void
           88 PROCESS(struct stream *stream, size_t n)
           89 {
           90         char *buf = stream->buf;
           91         TYPE *pixel, r, g, b;
           92         uint16_t *pixels, *end;
           93         uint16_t pixbuf[BUFSIZ / sizeof(uint16_t)];
           94         long int a, y, u, v;
           95         size_t ptr;
           96         pixels = pixbuf;
           97         end = pixbuf + ELEMENTSOF(pixbuf);
           98         if (draft) {
           99                 for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {
          100                         pixel = (TYPE *)(buf + ptr);
          101                         ciexyz_to_scaled_yuv(pixel[0], pixel[1], pixel[2], &r, &g, &b);
          102                         y = (long int)r + 0x1001L;
          103                         u = (long int)g + 0x8000L;
          104                         v = (long int)b + 0x8000L;
          105                         *pixels++ = 0xFFFFU;
          106                         *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));
          107                         *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));
          108                         *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));
          109                         if (pixels == end)
          110                                 ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");
          111                 }
          112         } else {
          113                 for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {
          114                         pixel = (TYPE *)(buf + ptr);
          115                         a = (long int)(pixel[3] * 0xFFFFL);
          116                         ciexyz_to_srgb(pixel[0], pixel[1], pixel[2], &r, &g, &b);
          117                         r = srgb_encode(r);
          118                         g = srgb_encode(g);
          119                         b = srgb_encode(b);
          120                         srgb_to_yuv(r, g, b, pixel + 0, pixel + 1, pixel + 2);
          121                         y = (long int)(pixel[0] * 0xDAF4L) + 0x1001L;
          122                         u = (long int)(pixel[1] * 0xFF00L) + 0x8000L;
          123                         v = (long int)(pixel[2] * 0xFF00L) + 0x8000L;
          124                         *pixels++ = htole((uint16_t)CLIP(0, a, 0xFFFFL));
          125                         *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));
          126                         *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));
          127                         *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));
          128                         if (pixels == end)
          129                                 ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");
          130                 }
          131         }
          132         ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), "<subprocess>");
          133 }
          134 
          135 #endif