History

vo: change draw_frame API to a boolean

x11 and wayland VOs + backends all have logic that skips drawing frames when the mpv isn't visible for efficiency reasons. This is implemented in each individual VO, but it is useful for the core to be aware of this as well. Currently, the display-sync modes on x11 do not try to be efficient and always render anyways because there is no blocking on the graphics API level if you skip rendering a frame (wayland works here by accident). This means mpv would otherwise blaze through frames which is not what anyone wants. We can instead improve this by implementing the blocking mechanism in the core and using that when appropriate. This commit does not implement that yet, but simply switches the draw_frame to a boolean. Receiving false means that the VO is not drawing frames and it should be treated as if the surface was hidden.

Dudemanguy committed 1 year ago

Commit 91c1b651 parent 753e20621 files · +93 −43Browse files

Unified · Split

21 files
  1. video/out/vo.h +5 −1
  2. video/out/vo_caca.c +5 −2
  3. video/out/vo_direct3d.c +7 −4
  4. video/out/vo_dmabuf_wayland.c +4 −2
  5. video/out/vo_drm.c +5 −2
  6. video/out/vo_gpu.c +5 −3
  7. video/out/vo_gpu_next.c +3 −2
  8. video/out/vo_image.c +5 −2
  9. video/out/vo_kitty.c +5 −2
  10. video/out/vo_lavc.c +6 −3
  11. video/out/vo_libmpv.c +2 −1
  12. video/out/vo_mediacodec_embed.c +2 −1
  13. video/out/vo_null.c +2 −1
  14. video/out/vo_sdl.c +5 −2
  15. video/out/vo_sixel.c +6 −3
  16. video/out/vo_tct.c +5 −2
  17. video/out/vo_vaapi.c +5 −2
  18. video/out/vo_vdpau.c +2 −1
  19. video/out/vo_wlshm.c +6 −3
  20. video/out/vo_x11.c +4 −2
  21. video/out/vo_xv.c +4 −2
video/out/vo.h+5−1
@@ -407,8 +407,12 @@ struct vo_driver { · 406 unmodified lines
407407 * frame is freed by the caller if the callee did not assume ownership
408408 * of the frames, but in any case the callee can still modify the
409409 * contained data and references.
410+ *
411+ * Return false to signal to the core that rendering is being skipped for
412+ * this particular frame. vo.c will sleep for the expected duration of that
413+ * frame before advancing forward.
410414 */
411− void (*draw_frame)(struct vo *vo, struct vo_frame *frame);
415+ bool (*draw_frame)(struct vo *vo, struct vo_frame *frame);
412416
413417 /*
414418 * Blit/Flip buffer to the screen. Must be called after each frame!
video/out/vo_caca.c+5−2
@@ -111,15 +111,18 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 110 unmodified lines
111111 return resize(vo);
112112 }
113113
114−static void draw_frame(struct vo *vo, struct vo_frame *frame)
114+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
115115 {
116116 struct priv *priv = vo->priv;
117117 struct mp_image *mpi = frame->current;
118118 if (!mpi)
119− return;
119+ goto done;
120120 memcpy_pic(priv->dither_buffer, mpi->planes[0], priv->image_width * depth, priv->image_height,
121121 priv->image_width * depth, mpi->stride[0]);
122122 caca_dither_bitmap(priv->canvas, 0, 0, priv->screen_w, priv->screen_h, priv->dither, priv->dither_buffer);
123+
124+done:
125+ return VO_TRUE;
123126 }
124127
125128 static void flip_page(struct vo *vo)
video/out/vo_direct3d.c+7−4
@@ -1003,18 +1003,18 @@ static bool get_video_buffer(d3d_priv *priv, struct mp_image *out) · 1002 unmodified lines
10031003 return true;
10041004 }
10051005
1006−static void draw_frame(struct vo *vo, struct vo_frame *frame)
1006+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
10071007 {
10081008 d3d_priv *priv = vo->priv;
10091009 if (!priv->d3d_device)
1010− return;
1010+ goto done;
10111011
10121012 struct mp_image buffer;
10131013 if (!get_video_buffer(priv, &buffer))
1014− return;
1014+ goto done;
10151015
10161016 if (!frame->current)
1017− return;
1017+ goto done;
10181018
10191019 mp_image_copy(&buffer, frame->current);
10201020
@@ -1024,6 +1024,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 3 unmodified lines
10241024 priv->osd_pts = frame->current->pts;
10251025
10261026 d3d_draw_frame(priv);
1027+
1028+done:
1029+ return VO_TRUE;
10271030 }
10281031
10291032 static mp_image_t *get_window_screenshot(d3d_priv *priv)
video/out/vo_dmabuf_wayland.c+4−2
@@ -592,7 +592,7 @@ done: · 591 unmodified lines
592592 return draw;
593593 }
594594
595−static void draw_frame(struct vo *vo, struct vo_frame *frame)
595+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
596596 {
597597 struct priv *p = vo->priv;
598598 struct vo_wayland_state *wl = vo->wl;
@@ -603,7 +603,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 4 unmodified lines
603603 if (!vo_wayland_check_visible(vo)) {
604604 if (frame->current)
605605 talloc_free(frame);
606− return;
606+ return VO_FALSE;
607607 }
608608
609609 if (p->destroy_buffers)
@@ -641,6 +641,8 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 31 unmodified lines
641641 p->osd_surface_is_mapped = false;
642642 }
643643 }
644+
645+ return VO_TRUE;
644646 }
645647
646648 static void flip_page(struct vo *vo)
video/out/vo_drm.c+5−2
@@ -300,13 +300,13 @@ static void swapchain_step(struct vo *vo) · 299 unmodified lines
300300 }
301301 }
302302
303−static void draw_frame(struct vo *vo, struct vo_frame *frame)
303+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
304304 {
305305 struct vo_drm_state *drm = vo->drm;
306306 struct priv *p = vo->priv;
307307
308308 if (!drm->active)
309− return;
309+ goto done;
310310
311311 drm->still = frame->still;
312312
@@ -319,6 +319,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 6 unmodified lines
319319 }
320320
321321 enqueue_frame(vo, fb);
322+
323+done:
324+ return VO_TRUE;
322325 }
323326
324327 static void queue_flip(struct vo *vo, struct drm_frame *frame)
video/out/vo_gpu.c+5−3
@@ -70,25 +70,27 @@ static void resize(struct vo *vo) · 69 unmodified lines
7070 vo->want_redraw = true;
7171 }
7272
73−static void draw_frame(struct vo *vo, struct vo_frame *frame)
73+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
7474 {
7575 struct gpu_priv *p = vo->priv;
7676 struct ra_swapchain *sw = p->ctx->swapchain;
7777
7878 struct ra_fbo fbo;
7979 if (!sw->fns->start_frame(sw, &fbo))
80− return;
80+ return VO_FALSE;
8181
8282 gl_video_render_frame(p->renderer, frame, &fbo, RENDER_FRAME_DEF);
8383 if (!sw->fns->submit_frame(sw, frame)) {
8484 MP_ERR(vo, "Failed presenting frame!\n");
85− return;
85+ return VO_FALSE;
8686 }
8787
8888 struct mp_image_params *params = gl_video_get_target_params_ptr(p->renderer);
8989 mp_mutex_lock(&vo->params_mutex);
9090 vo->target_params = params;
9191 mp_mutex_unlock(&vo->params_mutex);
92+
93+ return VO_TRUE;
9294 }
9395
9496 static void flip_page(struct vo *vo)
video/out/vo_gpu_next.c+3−2
@@ -904,7 +904,7 @@ static void update_tm_viz(struct pl_color_map_params *params, · 903 unmodified lines
904904 static void update_hook_opts_dynamic(struct priv *p, const struct pl_hook *hook,
905905 const struct mp_image *mpi);
906906
907−static void draw_frame(struct vo *vo, struct vo_frame *frame)
907+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
908908 {
909909 struct priv *p = vo->priv;
910910 pl_options pars = p->pars;
@@ -1029,7 +1029,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 118 unmodified lines
10291029 #endif
10301030 pl_queue_update(p->queue, NULL, &qparams);
10311031 }
1032− return;
1032+ return VO_FALSE;
10331033 }
10341034
10351035 bool valid = false;
@@ -1173,6 +1173,7 @@ done: · 137 unmodified lines
11731173
11741174 pl_gpu_flush(gpu);
11751175 p->frame_pending = true;
1176+ return VO_TRUE;
11761177 }
11771178
11781179 static void flip_page(struct vo *vo)
video/out/vo_image.c+5−2
@@ -90,16 +90,19 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 89 unmodified lines
9090 return 0;
9191 }
9292
93−static void draw_frame(struct vo *vo, struct vo_frame *frame)
93+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
9494 {
9595 struct priv *p = vo->priv;
9696 if (!frame->current)
97− return;
97+ goto done;
9898
9999 p->current = frame->current;
100100
101101 struct mp_osd_res dim = osd_res_from_image_params(vo->params);
102102 osd_draw_on_image(vo->osd, dim, frame->current->pts, OSD_DRAW_SUB_ONLY, p->current);
103+
104+done:
105+ return VO_TRUE;
103106 }
104107
105108 static void flip_page(struct vo *vo)
video/out/vo_kitty.c+5−2
@@ -239,7 +239,7 @@ static int create_shm(struct vo *vo) · 238 unmodified lines
239239 #endif
240240 }
241241
242−static void draw_frame(struct vo *vo, struct vo_frame *frame)
242+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
243243 {
244244 struct priv *p = vo->priv;
245245 mp_image_t *mpi = NULL;
@@ -273,7 +273,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 27 unmodified lines
273273
274274
275275 if (p->opts.use_shm && !create_shm(vo))
276− return;
276+ goto done;
277277
278278 memcpy_pic(p->buffer, p->frame->planes[0], p->width * BYTES_PER_PX,
279279 p->height, p->width * BYTES_PER_PX, p->frame->stride[0]);
@@ -282,6 +282,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 2 unmodified lines
282282 av_base64_encode(p->output, p->output_size, p->buffer, p->buffer_size);
283283
284284 talloc_free(mpi);
285+
286+done:
287+ return VO_TRUE;
285288 }
286289
287290 static void flip_page(struct vo *vo)
video/out/vo_lavc.c+6−3
@@ -182,7 +182,7 @@ static int query_format(struct vo *vo, int format) · 181 unmodified lines
182182 return 0;
183183 }
184184
185−static void draw_frame(struct vo *vo, struct vo_frame *voframe)
185+static bool draw_frame(struct vo *vo, struct vo_frame *voframe)
186186 {
187187 struct priv *vc = vo->priv;
188188 struct encoder_context *enc = vc->enc;
@@ -190,7 +190,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *voframe) · 1 unmodified line
190190 AVCodecContext *avc = enc->encoder;
191191
192192 if (voframe->redraw || voframe->repeat || voframe->num_frames < 1)
193− return;
193+ goto done;
194194
195195 struct mp_image *mpi = voframe->frames[0];
196196
@@ -198,7 +198,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *voframe) · 1 unmodified line
198198 osd_draw_on_image(vo->osd, dim, mpi->pts, OSD_DRAW_SUB_ONLY, mpi);
199199
200200 if (vc->shutdown)
201− return;
201+ goto done;
202202
203203 // Lock for shared timestamp fields.
204204 mp_mutex_lock(&ectx->lock);
@@ -241,6 +241,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *voframe) · 36 unmodified lines
241241 frame->quality = avc->global_quality;
242242 encoder_encode(enc, frame);
243243 av_frame_free(&frame);
244+
245+done:
246+ return VO_TRUE;
244247 }
245248
246249 static void flip_page(struct vo *vo)
video/out/vo_libmpv.c+2−1
@@ -485,7 +485,7 @@ int mpv_render_context_get_info(mpv_render_context *ctx, · 484 unmodified lines
485485 return res;
486486 }
487487
488−static void draw_frame(struct vo *vo, struct vo_frame *frame)
488+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
489489 {
490490 struct vo_priv *p = vo->priv;
491491 struct mpv_render_context *ctx = p->ctx;
@@ -498,6 +498,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 6 unmodified lines
498498 mp_mutex_unlock(&ctx->lock);
499499
500500 update(ctx);
501+ return VO_TRUE;
501502 }
502503
503504 static void flip_page(struct vo *vo)
video/out/vo_mediacodec_embed.c+2−1
@@ -76,7 +76,7 @@ static void flip_page(struct vo *vo) · 75 unmodified lines
7676 mp_image_unrefp(&p->next_image);
7777 }
7878
79−static void draw_frame(struct vo *vo, struct vo_frame *frame)
79+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
8080 {
8181 struct priv *p = vo->priv;
8282
@@ -86,6 +86,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 3 unmodified lines
8686
8787 talloc_free(p->next_image);
8888 p->next_image = mpi;
89+ return VO_TRUE;
8990 }
9091
9192 static int query_format(struct vo *vo, int format)
video/out/vo_null.c+2−1
@@ -32,8 +32,9 @@ struct priv { · 31 unmodified lines
3232 double cfg_fps;
3333 };
3434
35−static void draw_frame(struct vo *vo, struct vo_frame *frame)
35+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
3636 {
37+ return VO_TRUE;
3738 }
3839
3940 static void flip_page(struct vo *vo)
video/out/vo_sdl.c+5−2
@@ -879,7 +879,7 @@ static int query_format(struct vo *vo, int format) · 878 unmodified lines
879879 return 0;
880880 }
881881
882−static void draw_frame(struct vo *vo, struct vo_frame *frame)
882+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
883883 {
884884 struct priv *vc = vo->priv;
885885
@@ -894,7 +894,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 8 unmodified lines
894894
895895 mp_image_t texmpi;
896896 if (!lock_texture(vo, &texmpi))
897− return;
897+ goto done;
898898
899899 mp_image_copy(&texmpi, frame->current);
900900
@@ -914,6 +914,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 13 unmodified lines
914914 SDL_RenderCopy(vc->renderer, vc->tex, &src, &dst);
915915
916916 draw_osd(vo);
917+
918+done:
919+ return VO_TRUE;
917920 }
918921
919922 static struct mp_image *get_window_screenshot(struct vo *vo)
video/out/vo_sixel.c+6−3
@@ -378,7 +378,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 377 unmodified lines
378378 return ret;
379379 }
380380
381−static void draw_frame(struct vo *vo, struct vo_frame *frame)
381+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
382382 {
383383 struct priv *priv = vo->priv;
384384 SIXELSTATUS status;
@@ -391,7 +391,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 6 unmodified lines
391391 bool resized = false;
392392 update_canvas_dimensions(vo);
393393 if (!priv->canvas_ok)
394− return;
394+ goto done;
395395
396396 if (prev_rows != priv->num_rows || prev_cols != priv->num_cols ||
397397 prev_width != vo->dwidth || prev_height != vo->dheight)
@@ -409,7 +409,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 11 unmodified lines
409409 if (frame->repeat && !frame->redraw && !resized) {
410410 // Frame is repeated, and no need to update OSD either
411411 priv->skip_frame_draw = true;
412− return;
412+ goto done;
413413 } else {
414414 // Either frame is new, or OSD has to be redrawn
415415 priv->skip_frame_draw = false;
@@ -457,6 +457,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 41 unmodified lines
457457
458458 if (mpi)
459459 talloc_free(mpi);
460+
461+done:
462+ return VO_TRUE;
460463 }
461464
462465 static void flip_page(struct vo *vo)
video/out/vo_tct.c+5−2
@@ -253,14 +253,17 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 252 unmodified lines
253253 return 0;
254254 }
255255
256−static void draw_frame(struct vo *vo, struct vo_frame *frame)
256+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
257257 {
258258 struct priv *p = vo->priv;
259259 struct mp_image *src = frame->current;
260260 if (!src)
261− return;
261+ goto done;
262262 // XXX: pan, crop etc.
263263 mp_sws_scale(p->sws, p->frame, src);
264+
265+done:
266+ return VO_TRUE;
264267 }
265268
266269 static void flip_page(struct vo *vo)
video/out/vo_vaapi.c+5−2
@@ -555,7 +555,7 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info) · 554 unmodified lines
555555 present_sync_get_info(x11->present, info);
556556 }
557557
558−static void draw_frame(struct vo *vo, struct vo_frame *frame)
558+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
559559 {
560560 struct priv *p = vo->priv;
561561 struct mp_image *mpi = frame->current;
@@ -564,7 +564,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 2 unmodified lines
564564 struct mp_image *dst = p->swdec_surfaces[p->output_surface];
565565 if (!dst || va_surface_upload(p, dst, mpi) < 0) {
566566 MP_WARN(vo, "Could not upload surface.\n");
567− return;
567+ goto done;
568568 }
569569 mp_image_copy_attributes(dst, mpi);
570570 mpi = dst;
@@ -573,6 +573,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 2 unmodified lines
573573 p->output_surfaces[p->output_surface] = mpi;
574574
575575 draw_osd(vo);
576+
577+done:
578+ return VO_TRUE;
576579 }
577580
578581 static void free_subpicture(struct priv *p, struct vaapi_osd_image *img)
video/out/vo_vdpau.c+2−1
@@ -870,7 +870,7 @@ drop: · 869 unmodified lines
870870 vo_increment_drop_count(vo, 1);
871871 }
872872
873−static void draw_frame(struct vo *vo, struct vo_frame *frame)
873+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
874874 {
875875 struct vdpctx *vc = vo->priv;
876876
@@ -893,6 +893,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 16 unmodified lines
893893 video_to_output_surface(vo, vc->current_image);
894894 draw_osd(vo);
895895 }
896+ return VO_TRUE;
896897 }
897898
898899 // warning: the size and pixel format of surface must match that of the
video/out/vo_wlshm.c+6−3
@@ -239,7 +239,7 @@ static int control(struct vo *vo, uint32_t request, void *data) · 238 unmodified lines
239239 return ret;
240240 }
241241
242−static void draw_frame(struct vo *vo, struct vo_frame *frame)
242+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
243243 {
244244 struct priv *p = vo->priv;
245245 struct vo_wayland_state *wl = vo->wl;
@@ -248,7 +248,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 2 unmodified lines
248248
249249 bool render = vo_wayland_check_visible(vo);
250250 if (!render)
251− return;
251+ return VO_FALSE;
252252
253253 buf = p->free_buffers;
254254 if (buf) {
@@ -257,7 +257,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 2 unmodified lines
257257 buf = buffer_create(vo, vo->dwidth, vo->dheight);
258258 if (!buf) {
259259 wl_surface_attach(wl->surface, NULL, 0, 0);
260− return;
260+ goto done;
261261 }
262262 }
263263 if (src) {
@@ -289,6 +289,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 25 unmodified lines
289289 osd_draw_on_image(vo->osd, p->osd, 0, 0, &buf->mpi);
290290 }
291291 wl_surface_attach(wl->surface, buf->buffer, 0, 0);
292+
293+done:
294+ return VO_TRUE;
292295 }
293296
294297 static void flip_page(struct vo *vo)
video/out/vo_x11.c+4−2
@@ -327,14 +327,14 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info) · 326 unmodified lines
327327 present_sync_get_info(x11->present, info);
328328 }
329329
330−static void draw_frame(struct vo *vo, struct vo_frame *frame)
330+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
331331 {
332332 struct priv *p = vo->priv;
333333
334334 wait_for_completion(vo, 1);
335335 bool render = vo_x11_check_visible(vo);
336336 if (!render)
337− return;
337+ return VO_FALSE;
338338
339339 struct mp_image *img = &p->mp_ximages[p->current_buf];
340340
@@ -359,6 +359,8 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 18 unmodified lines
359359
360360 if (frame->current != p->original_image)
361361 p->original_image = frame->current;
362+
363+ return VO_TRUE;
362364 }
363365
364366 static int query_format(struct vo *vo, int format)
video/out/vo_xv.c+4−2
@@ -708,14 +708,14 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info) · 707 unmodified lines
708708 present_sync_get_info(x11->present, info);
709709 }
710710
711−static void draw_frame(struct vo *vo, struct vo_frame *frame)
711+static bool draw_frame(struct vo *vo, struct vo_frame *frame)
712712 {
713713 struct xvctx *ctx = vo->priv;
714714
715715 wait_for_completion(vo, ctx->num_buffers - 1);
716716 bool render = vo_x11_check_visible(vo);
717717 if (!render)
718− return;
718+ return VO_FALSE;
719719
720720 struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf);
721721 if (frame->current) {
@@ -729,6 +729,8 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) · 7 unmodified lines
729729
730730 if (frame->current != ctx->original_image)
731731 ctx->original_image = frame->current;
732+
733+ return VO_TRUE;
732734 }
733735
734736 static int query_format(struct vo *vo, int format)

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