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