blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | 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