diff options
author | Niklas Haas <git@haasn.dev> | 2021-11-22 12:38:43 +0100 |
---|---|---|
committer | Niklas Haas <git@haasn.dev> | 2021-11-22 12:38:43 +0100 |
commit | 2b2442ee67913221e5c87cbc06010671e1b41c15 (patch) | |
tree | cbe386bccfc0f230b78a71789ceaf81431165abf /video/out | |
parent | 67c1ff8dad2ba8dafcf60436d7d513d114a7eabf (diff) | |
download | mpv-2b2442ee67913221e5c87cbc06010671e1b41c15.tar.bz2 mpv-2b2442ee67913221e5c87cbc06010671e1b41c15.tar.xz |
vo_gpu_next: apply csp overrides for RGB/XYZ/YUV formats
This is needed when the color system is not explicitly tagged, but
instead needs to be inferred by the VO.
Note that there exists the function mp_image_params_guess_csp for this
sort of stuff, but it contains a lot of baggage that I don't want to
replicate, in order to move as much of this logic into pl_renderer as
possible, and therefore also give it the best chance of knowing what
shortcuts it can and can't take.
Fixes the other half of https://github.com/mpv-player/mpv/issues/9499
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/vo_gpu_next.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 72596a3cba..ca19a612ea 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -391,34 +391,50 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src struct pl_frame *frame) { struct mp_image *mpi = src->frame_data; + const struct mp_image_params *par = &mpi->params; struct frame_priv *fp = mpi->priv; struct pl_plane_data data[4] = {0}; struct vo *vo = fp->vo; struct priv *p = vo->priv; // TODO: implement support for hwdec wrappers - *frame = (struct pl_frame) { .num_planes = mpi->num_planes, .color = { - .primaries = mp_prim_to_pl(mpi->params.color.primaries), - .transfer = mp_trc_to_pl(mpi->params.color.gamma), - .light = mp_light_to_pl(mpi->params.color.light), - .sig_peak = mpi->params.color.sig_peak, + .primaries = mp_prim_to_pl(par->color.primaries), + .transfer = mp_trc_to_pl(par->color.gamma), + .light = mp_light_to_pl(par->color.light), + .sig_peak = par->color.sig_peak, }, .repr = { - .sys = mp_csp_to_pl(mpi->params.color.space), - .levels = mp_levels_to_pl(mpi->params.color.levels), - .alpha = mp_alpha_to_pl(mpi->params.alpha), + .sys = mp_csp_to_pl(par->color.space), + .levels = mp_levels_to_pl(par->color.levels), + .alpha = mp_alpha_to_pl(par->alpha), }, .profile = { .data = mpi->icc_profile ? mpi->icc_profile->data : NULL, .len = mpi->icc_profile ? mpi->icc_profile->size : 0, }, - .rotation = mpi->params.rotate / 90, + .rotation = par->rotate / 90, }; - enum pl_chroma_location chroma = mp_chroma_to_pl(mpi->params.chroma_location); + // mp_image, like AVFrame, likes communicating RGB/XYZ/YCbCr status + // implicitly via the image format, rather than the actual tagging. + switch (mp_imgfmt_get_forced_csp(par->imgfmt)) { + case MP_CSP_RGB: + frame->repr.sys = PL_COLOR_SYSTEM_RGB; + frame->repr.levels = PL_COLOR_LEVELS_FULL; + break; + case MP_CSP_XYZ: + frame->repr.sys = PL_COLOR_SYSTEM_XYZ; + break; + case MP_CSP_AUTO: + frame->repr.sys = pl_color_system_guess_ycbcr(par->w, par->h); + break; + default: break; + } + + enum pl_chroma_location chroma = mp_chroma_to_pl(par->chroma_location); int planes = plane_data_from_imgfmt(data, &frame->repr.bits, mpi->imgfmt); for (int n = 0; n < planes; n++) { data[n].width = mp_image_plane_w(mpi, n); @@ -457,7 +473,7 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src struct mp_osd_res vidres = { .w = mpi->w, .h = mpi->h, // compensate for anamorphic sources (render subtitles as normal) - .display_par = (float) mpi->params.p_h / mpi->params.p_w, + .display_par = (float) par->p_h / par->p_w, }; write_overlays(vo, vidres, mpi->pts, OSD_DRAW_SUB_ONLY, &fp->subs, frame); |