| blind-repeat: add -f and fix reading from file bug - blind - suckless command-l… | |
| git clone git://git.suckless.org/blind | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 3e0822a8a5127a5ba395bc506622af73d75af0ab | |
| parent bbd8ee77641288bb9051c99bc90d294ec1baa7cb | |
| Author: Mattias Andrée <[email protected]> | |
| Date: Sat, 3 Jun 2017 18:38:37 +0200 | |
| blind-repeat: add -f and fix reading from file bug | |
| Signed-off-by: Mattias Andrée <[email protected]> | |
| Diffstat: | |
| M TODO | 2 -- | |
| M man/blind-repeat.1 | 16 +++++++++++++++- | |
| M src/blind-repeat.c | 59 +++++++++++++++++++++++++++--… | |
| 3 files changed, 68 insertions(+), 9 deletions(-) | |
| --- | |
| diff --git a/TODO b/TODO | |
| @@ -56,8 +56,6 @@ bug: blind-stack: cannot use file outside /dev/fd/ | |
| Add [-j jobs] to blind-from-video and blind-to-video. | |
| -Add -f (framewise) to blind-repeat | |
| - | |
| Generate a header file with the appropriate values for USING_BINARY32, USING_B… | |
| long double is slightly faster than long. | |
| long double (xyza q) could be added as another format. | |
| diff --git a/man/blind-repeat.1 b/man/blind-repeat.1 | |
| @@ -3,7 +3,8 @@ | |
| blind-repeat - Repeat a video | |
| .SH SYNOPSIS | |
| .B blind-repeat | |
| -.RI ( count | |
| +([-f] | |
| +.I count | |
| | | |
| .RB ' inf ') | |
| .I file | |
| @@ -33,12 +34,25 @@ will read stdin into memory; you are highly discouraged | |
| from using this unless stdin is a single frame, or known | |
| to only be a very small number of frames, is it can | |
| potentially use all of the computer's memory. | |
| +.SH OPTIONS | |
| +.TP | |
| +.B -f | |
| +Repeat each frames | |
| +.B count | |
| +times before copying the next frame, rather than | |
| +copying the entire video | |
| +.B count | |
| +times. | |
| .SH REQUIREMENTS | |
| .B blind-repeat | |
| requires enough free memory to load the entire video | |
| into memory if it is read from stdin. A frame requires | |
| 32 bytes per pixel it contains. So for a 720p video at | |
| 25 Hz, 1 GB is reached in just below 1.5 seconds. | |
| +However, if | |
| +.B -f | |
| +is used, only a full video frame will be loaded into | |
| +memory rather than an entire video, if reading from stdin. | |
| .SH SEE ALSO | |
| .BR blind (7), | |
| .BR blind-from-image (1) | |
| diff --git a/src/blind-repeat.c b/src/blind-repeat.c | |
| @@ -1,7 +1,7 @@ | |
| /* See LICENSE file for copyright and license details. */ | |
| #include "common.h" | |
| -USAGE("(count | 'inf') file") | |
| +USAGE("([-f] count | 'inf') file") | |
| static size_t count = 0; | |
| static int inf; | |
| @@ -10,6 +10,7 @@ static struct stream stream; | |
| static int | |
| repeat_regular_file(void) | |
| { | |
| + stream.ptr = 0; | |
| while (inf || count--) { | |
| fadvise_sequential(stream.fd, (off_t)(stream.headlen), 0); | |
| elseek(stream.fd, (off_t)(stream.headlen), SEEK_SET, stream.fi… | |
| @@ -20,6 +21,22 @@ repeat_regular_file(void) | |
| } | |
| static int | |
| +repeat_regular_file_framewise(void) | |
| +{ | |
| + size_t i; | |
| + off_t off = (off_t)(stream.headlen); | |
| + stream.ptr = 0; | |
| + echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, "input"); | |
| + for (;; off += (off_t)(stream.frame_size)) { | |
| + for (i = 0; i < count; i++) { | |
| + elseek(stream.fd, off, SEEK_SET, stream.file); | |
| + if (!esend_frames(&stream, STDOUT_FILENO, 1, "<stdout>… | |
| + return 0; | |
| + } | |
| + } | |
| +} | |
| + | |
| +static int | |
| repeat_stdin(void) | |
| { | |
| size_t ptr = stream.ptr; | |
| @@ -32,24 +49,54 @@ repeat_stdin(void) | |
| return free(buf), 0; | |
| } | |
| +static int | |
| +repeat_stdin_framewise(void) | |
| +{ | |
| + char *buf; | |
| + size_t i; | |
| + echeck_dimensions(&stream, WIDTH | HEIGHT, "input"); | |
| + buf = emalloc(stream.frame_size); | |
| + while (eread_frame(&stream, buf)) | |
| + for (i = 0; i < count; i++) | |
| + if (writeall(STDOUT_FILENO, buf, stream.frame_size)) | |
| + return free(buf), -1; | |
| + return free(buf), 0; | |
| +} | |
| + | |
| int | |
| main(int argc, char *argv[]) | |
| { | |
| - UNOFLAGS(argc != 2); | |
| + int framewise = 0; | |
| - if ((inf = !strcmp(argv[0], "inf"))) | |
| + ARGBEGIN { | |
| + case 'f': | |
| + framewise = 1; | |
| + break; | |
| + default: | |
| + usage(); | |
| + } ARGEND; | |
| + | |
| + if (argc != 2) | |
| + usage(); | |
| + | |
| + if ((inf = !strcmp(argv[0], "inf"))) { | |
| + if (framewise) | |
| + usage(); | |
| einf_check_fd(STDOUT_FILENO, "<stdout>"); | |
| - else | |
| + } else { | |
| count = etozu_arg("the count", argv[0], 0, SIZE_MAX); | |
| + } | |
| eopen_stream(&stream, !strcmp(argv[1], "-") ? NULL : argv[1]); | |
| - if (count > SIZE_MAX / stream.frames) | |
| + if (stream.frames && count > SIZE_MAX / stream.frames) | |
| eprintf("%s: video is too long\n", stream.file); | |
| stream.frames *= count; | |
| fprint_stream_head(stdout, &stream); | |
| efflush(stdout, "<stdout>"); | |
| - if (!strcmp(argv[1], "-") ? repeat_stdin() : repeat_regular_file()) | |
| + if (!strcmp(argv[1], "-") | |
| + ? (framewise ? repeat_stdin_framewise() : repeat_stdin()) | |
| + : (framewise ? repeat_regular_file_framewise(): repeat_regular_fil… | |
| if (!inf || errno != EPIPE) | |
| eprintf("write <stdout>:"); | |