vo_gpu_next: fix OSD rendering of screenshots

One downside of this approach is that it bypasses the mixer cache, but
while this is not ideal for performance reasons, the status quo is also
simply broken so I'd rather have a slower implementation that works than
a faster implementation that does not.

And as it turns out, updating the OSD state and invalidating the mixer
cache correctly is sufficiently nontrivial to do in a clean way, so I'd
rather have this code that I can be reasonably certain does the right
thing.

Fixes #9923 as discussed. Also fixes #9928.
This commit is contained in:
Niklas Haas 2022-06-05 20:00:10 +02:00 committed by Niklas Haas
parent c4c7b07acf
commit 969bdf5f41
1 changed files with 6 additions and 5 deletions

View File

@ -1109,8 +1109,8 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args)
// Passing an interpolation radius of 0 guarantees that the first frame in
// the resulting mix is the correct frame for this PTS
struct pl_frame *image = (struct pl_frame *) mix.frames[0];
struct mp_image *mpi = image->user_data;
struct pl_frame image = *(struct pl_frame *) mix.frames[0];
struct mp_image *mpi = image.user_data;
struct mp_rect src = p->src, dst = p->dst;
struct mp_osd_res osd = p->osd_res;
if (!args->scaled) {
@ -1159,7 +1159,7 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args)
};
apply_target_options(p, &target);
apply_crop(image, src, mpi->params.w, mpi->params.h);
apply_crop(&image, src, mpi->params.w, mpi->params.h);
apply_crop(&target, dst, fbo->params.w, fbo->params.h);
int osd_flags = 0;
@ -1167,9 +1167,10 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args)
osd_flags |= OSD_DRAW_OSD_ONLY;
if (!args->osd)
osd_flags |= OSD_DRAW_SUB_ONLY;
update_overlays(vo, osd, 0, osd_flags, &p->osd_state, &target);
update_overlays(vo, osd, mpi->pts, osd_flags, &p->osd_state, &target);
image.num_overlays = 0; // Disable on-screen overlays
if (!pl_render_image_mix(p->rr, &mix, &target, &p->params)) {
if (!pl_render_image(p->rr, &image, &target, &p->params)) {
MP_ERR(vo, "Failed rendering frame!\n");
goto done;
}