summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2021-11-22 12:38:43 +0100
committerNiklas Haas <git@haasn.dev>2021-11-22 12:38:43 +0100
commit2b2442ee67913221e5c87cbc06010671e1b41c15 (patch)
treecbe386bccfc0f230b78a71789ceaf81431165abf
parent67c1ff8dad2ba8dafcf60436d7d513d114a7eabf (diff)
downloadmpv-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
-rw-r--r--video/out/vo_gpu_next.c38
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);