History

video/out/kitty: make kitty vo ten times faster by avoiding strlen

When playing a video, 55% of CPU used in strlen, callgraph flip_page: ta_talloc_strdup_append , ta_talloc_asprintf_append and ta_talloc_strndup_append . Before the fix: 2 fps when playing 1080p 24 fps video (--vo-kitty-use-shm=no), 24 fps after the fix. video/out/kitty: move bstr cmd to priv

Sami Farin committed 1 year ago

Commit fa9c2a31 parent 38ad1ed1 file · +38 −26Browse files

Unified · Split

video/out/vo_kitty.c+38−26
@@ -48,7 +48,7 @@ · 47 unmodified lines
48#define DEFAULT_WIDTH 8048#define DEFAULT_WIDTH 80
49#define DEFAULT_HEIGHT 2549#define DEFAULT_HEIGHT 25
50 50
51static inline void write_str(const char *s)51static inline void write_bstr(bstr bs)
52{52{
53 // On POSIX platforms, write() is the fastest method. It also is the only53 // On POSIX platforms, write() is the fastest method. It also is the only
54 // one that allows atomic writes so mpv’s output will not be interrupted54 // one that allows atomic writes so mpv’s output will not be interrupted
@@ -57,25 +57,31 @@ static inline void write_str(const char *s) · 2 unmodified lines
57 // exceeding PIPE_BUF, but at least Linux does seem to implement it that57 // exceeding PIPE_BUF, but at least Linux does seem to implement it that
58 // way.58 // way.
59#if HAVE_POSIX59#if HAVE_POSIX
60 int remain = strlen(s);60 size_t remain = bs.len;
61 unsigned char *pos = bs.start;
61 while (remain > 0) {62 while (remain > 0) {
62 ssize_t written = write(STDOUT_FILENO, s, remain);63 ssize_t written = write(STDOUT_FILENO, pos, remain);
63 if (written < 0)64 if (written < 0)
64 return;65 return;
65 remain -= written;66 remain -= written;
66 s += written;67 pos += written;
67 }68 }
68#else69#else
69 printf("%s", s);70 fwrite(bs.start, 1, bs.len, stdout);
70 fflush(stdout);71 fflush(stdout);
71#endif72#endif
72}73}
73 74
75static inline void write_str(unsigned char* s)
76{
77 write_bstr(bstr0(s));
78}
79
74#define KITTY_ESC_IMG "\033_Ga=T,f=24,s=%d,v=%d,C=1,q=2,m=1;"80#define KITTY_ESC_IMG "\033_Ga=T,f=24,s=%d,v=%d,C=1,q=2,m=1;"
75#define KITTY_ESC_IMG_SHM "\033_Ga=T,t=s,f=24,s=%d,v=%d,C=1,q=2,m=1;%s\033\\"81#define KITTY_ESC_IMG_SHM "\033_Ga=T,t=s,f=24,s=%d,v=%d,C=1,q=2,m=1;%s\033\\"
76#define KITTY_ESC_CONTINUE "\033_Gm=%d;"82#define KITTY_ESC_CONTINUE "\033_Gm=%d;"
77#define KITTY_ESC_END "\033\\"83static const bstr KITTY_ESC_END = bstr0_lit("\033\\");
78#define KITTY_ESC_DELETE_ALL "\033_Ga=d;\033\\"84static const bstr KITTY_ESC_DELETE_ALL = bstr0_lit("\033_Ga=d;\033\\");
79 85
80struct vo_kitty_opts {86struct vo_kitty_opts {
81 int width, height, top, left, rows, cols;87 int width, height, top, left, rows, cols;
@@ -91,6 +97,7 @@ struct priv { · 9 unmodified lines
91 char *shm_path, *shm_path_b64;97 char *shm_path, *shm_path_b64;
92 int buffer_size, output_size;98 int buffer_size, output_size;
93 int shm_fd;99 int shm_fd;
100 bstr cmd;
94 101
95 int left, top, width, height, cols, rows;102 int left, top, width, height, cols, rows;
96 103
@@ -126,6 +133,7 @@ static void free_bufs(struct vo* vo) · 29 unmodified lines
126 133
127 talloc_free(p->frame);134 talloc_free(p->frame);
128 talloc_free(p->output);135 talloc_free(p->output);
136 talloc_free(p->cmd.start);
129 137
130 if (p->opts.use_shm) {138 if (p->opts.use_shm) {
131 close_shm(p);139 close_shm(p);
@@ -177,7 +185,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 45 unmodified lines
177 struct priv *p = vo->priv;185 struct priv *p = vo->priv;
178 186
179 vo->want_redraw = true;187 vo->want_redraw = true;
180 write_str(KITTY_ESC_DELETE_ALL);188 write_bstr(KITTY_ESC_DELETE_ALL);
181 if (p->opts.config_clear)189 if (p->opts.config_clear)
182 write_str(TERM_ESC_CLEAR_SCREEN);190 write_str(TERM_ESC_CLEAR_SCREEN);
183 191
@@ -292,36 +300,40 @@ done: · 108 unmodified lines
292 300
293static void flip_page(struct vo *vo)301static void flip_page(struct vo *vo)
294{302{
295 struct priv* p = vo->priv;303 struct priv *p = vo->priv;
296 304 if (!p->buffer)
297 if (p->buffer == NULL)
298 return;305 return;
299 306
300 char *cmd = talloc_asprintf(NULL, TERM_ESC_GOTO_YX, p->top, p->left);307 p->cmd.len = 0;
308
309 // Start with ESC to position the cursor
310 bstr_xappend_asprintf(NULL, &p->cmd, TERM_ESC_GOTO_YX, p->top, p->left);
301 311
302 if (p->opts.use_shm) {312 if (p->opts.use_shm) {
303 cmd = talloc_asprintf_append(cmd, KITTY_ESC_IMG_SHM, p->width, p->height, p->shm_path_b64);313 bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_IMG_SHM,
314 p->width, p->height, p->shm_path_b64);
304 } else {315 } else {
305 if (p->output == NULL) {316 if (!p->output) {
306 talloc_free(cmd);
307 return;317 return;
308 }318 }
309 319
310 cmd = talloc_asprintf_append(cmd, KITTY_ESC_IMG, p->width, p->height);320 bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_IMG, p->width, p->height);
311 for (int offset = 0, noffset;; offset += noffset) {321
312 if (offset)322 for (int offset = 0; offset < p->output_size; ) {
313 cmd = talloc_asprintf_append(cmd, KITTY_ESC_CONTINUE, offset < p->output_size);323 int chunk = MPMIN(4096, p->output_size - offset);
314 noffset = MPMIN(4096, p->output_size - offset);324
315 cmd = talloc_strndup_append(cmd, p->output + offset, noffset);325 if (offset > 0)
316 cmd = talloc_strdup_append(cmd, KITTY_ESC_END);326 bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_CONTINUE,
327 offset + chunk < p->output_size);
317 328
318 if (offset >= p->output_size)329 // Append at max chunk bytes
319 break;330 bstr_xappend(NULL, &p->cmd, (bstr){p->output + offset, chunk});
331 bstr_xappend(NULL, &p->cmd, KITTY_ESC_END);
332 offset += chunk;
320 }333 }
321 }334 }
322 335
323 write_str(cmd);336 write_bstr(p->cmd);
324 talloc_free(cmd);
325 337
326#if HAVE_POSIX338#if HAVE_POSIX
327 if (p->opts.use_shm)339 if (p->opts.use_shm)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t