diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index ef4fcd99b5..8803e5b045 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -271,9 +271,12 @@ static struct mp_image *get_image(struct vo *vo, int imgfmt, int w, int h, return mpi; } -static void update_overlays(struct vo *vo, struct mp_osd_res res, double pts, +static struct pl_color_space get_mpi_csp(struct vo *vo, struct mp_image *mpi); + +static void update_overlays(struct vo *vo, struct mp_osd_res res, int flags, enum pl_overlay_coords coords, - struct osd_state *state, struct pl_frame *frame) + struct osd_state *state, struct pl_frame *frame, + struct mp_image *src) { struct priv *p = vo->priv; static const bool subfmt_all[SUBBITMAP_COUNT] = { @@ -281,6 +284,7 @@ static void update_overlays(struct vo *vo, struct mp_osd_res res, double pts, [SUBBITMAP_BGRA] = true, }; + double pts = src ? src->pts : 0; struct sub_bitmap_list *subs = osd_render(vo->osd, res, pts, flags, subfmt_all); frame->overlays = state->overlays; frame->num_overlays = 0; @@ -337,22 +341,27 @@ static void update_overlays(struct vo *vo, struct mp_osd_res res, double pts, .tex = entry->tex, .parts = entry->parts, .num_parts = entry->num_parts, - .color.primaries = frame->color.primaries, - .color.transfer = frame->color.transfer, + .color = { + .primaries = PL_COLOR_PRIM_BT_709, + .transfer = PL_COLOR_TRC_SRGB, + }, .coords = coords, }; - // Reject HDR/wide gamut subtitles out of the box, since these are - // probably not intended to match the video color space. - if (pl_color_primaries_is_wide_gamut(ol->color.primaries)) - ol->color.primaries = PL_COLOR_PRIM_UNKNOWN; - if (pl_color_transfer_is_hdr(ol->color.transfer)) - ol->color.transfer = PL_COLOR_TRC_UNKNOWN; - switch (item->format) { case SUBBITMAP_BGRA: ol->mode = PL_OVERLAY_NORMAL; ol->repr.alpha = PL_ALPHA_PREMULTIPLIED; + // Infer bitmap colorspace from source + if (src) { + ol->color = get_mpi_csp(vo, src); + // Seems like HDR subtitles are targeting SDR white + if (pl_color_transfer_is_hdr(ol->color.transfer)) { + ol->color.hdr = (struct pl_hdr_metadata) { + .max_luma = PL_COLOR_SDR_WHITE, + }; + } + } break; case SUBBITMAP_LIBASS: ol->mode = PL_OVERLAY_MONOCHROME; @@ -1027,9 +1036,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) struct pl_frame target; pl_frame_from_swapchain(&target, &swframe); apply_target_options(p, &target); - update_overlays(vo, p->osd_res, frame->current ? frame->current->pts : 0, + update_overlays(vo, p->osd_res, (frame->current && opts->blend_subs) ? OSD_DRAW_OSD_ONLY : 0, - PL_OVERLAY_COORDS_DST_FRAME, &p->osd_state, &target); + PL_OVERLAY_COORDS_DST_FRAME, &p->osd_state, &target, frame->current); apply_crop(&target, p->dst, swframe.fbo->params.w, swframe.fbo->params.h); update_tm_viz(&pars->color_map_params, &target); @@ -1087,9 +1096,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) .mb = (image->crop.y1 - vo->params->h) * ry, .display_par = 1.0, }; - update_overlays(vo, res, mpi->pts, OSD_DRAW_SUB_ONLY, + update_overlays(vo, res, OSD_DRAW_SUB_ONLY, PL_OVERLAY_COORDS_DST_CROP, - &fp->subs, image); + &fp->subs, image, mpi); fp->osd_sync = p->osd_sync; } } else { @@ -1406,13 +1415,13 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args) .mb = (image.crop.y1 - vo->params->h) * ry, .display_par = 1.0, }; - update_overlays(vo, res, mpi->pts, osd_flags, + update_overlays(vo, res, osd_flags, PL_OVERLAY_COORDS_DST_CROP, - &fp->subs, &image); + &fp->subs, &image, mpi); } else { // Disable overlays when blend_subs is disabled - update_overlays(vo, osd, mpi->pts, osd_flags, PL_OVERLAY_COORDS_DST_FRAME, - &p->osd_state, &target); + update_overlays(vo, osd, osd_flags, PL_OVERLAY_COORDS_DST_FRAME, + &p->osd_state, &target, mpi); image.num_overlays = 0; }