mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 03:52:22 +02:00
vo_gpu: fix green shit with float yuv input
This was incorrect at least because the colorspace matrix attempted to center chroma at (conceptually) 0.5, instead of 0. Also, it tried to apply the fixed point shift logic for component sizes > 8 bit. There is no float yuv format in mpv/ffmpeg yet, but see next commit, which enables zimg to output it. I'm assuming zimg defines this format such that luma is in range [0,1] and chroma in range [-0.5,0.5], with the levels flag being ignored. This is consistent with H264/5 Annex E (I think...), and it sort of seems to look right, so that's it.
This commit is contained in:
parent
4019c11314
commit
9e48085043
@ -738,6 +738,9 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||
abort();
|
||||
};
|
||||
|
||||
if (params->is_float)
|
||||
levels_in = -1;
|
||||
|
||||
if ((colorspace == MP_CSP_BT_601 || colorspace == MP_CSP_BT_709 ||
|
||||
colorspace == MP_CSP_SMPTE_240M || colorspace == MP_CSP_BT_2020_NC))
|
||||
{
|
||||
|
@ -162,6 +162,8 @@ struct mp_csp_params {
|
||||
float gamma;
|
||||
// discard U/V components
|
||||
bool gray;
|
||||
// input is already centered and range-expanded
|
||||
bool is_float;
|
||||
// texture_bits/input_bits is for rescaling fixed point input to range [0,1]
|
||||
int texture_bits;
|
||||
int input_bits;
|
||||
|
@ -283,11 +283,10 @@ static const struct ra_format *find_plane_format(struct ra *ra, int bytes,
|
||||
// Returns false (and *out is not touched) if no format found.
|
||||
bool ra_get_imgfmt_desc(struct ra *ra, int imgfmt, struct ra_imgfmt_desc *out)
|
||||
{
|
||||
struct ra_imgfmt_desc res = {0};
|
||||
struct ra_imgfmt_desc res = {.component_type = RA_CTYPE_UNKNOWN};
|
||||
|
||||
struct mp_regular_imgfmt regfmt;
|
||||
if (mp_get_regular_imgfmt(®fmt, imgfmt)) {
|
||||
enum ra_ctype ctype = RA_CTYPE_UNKNOWN;
|
||||
res.num_planes = regfmt.num_planes;
|
||||
res.component_bits = regfmt.component_size * 8;
|
||||
res.component_pad = regfmt.component_pad;
|
||||
@ -305,9 +304,10 @@ bool ra_get_imgfmt_desc(struct ra *ra, int imgfmt, struct ra_imgfmt_desc *out)
|
||||
res.component_pad < 0)
|
||||
return false;
|
||||
// Renderer restriction, but actually an unwanted corner case.
|
||||
if (ctype != RA_CTYPE_UNKNOWN && ctype != res.planes[n]->ctype)
|
||||
if (res.component_type != RA_CTYPE_UNKNOWN &&
|
||||
res.component_type != res.planes[n]->ctype)
|
||||
return false;
|
||||
ctype = res.planes[n]->ctype;
|
||||
res.component_type = res.planes[n]->ctype;
|
||||
}
|
||||
res.chroma_w = 1 << regfmt.chroma_xs;
|
||||
res.chroma_h = 1 << regfmt.chroma_ys;
|
||||
@ -330,6 +330,16 @@ supported:
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *ctype_to_str(enum ra_ctype ctype)
|
||||
{
|
||||
switch (ctype) {
|
||||
case RA_CTYPE_UNORM: return "unorm";
|
||||
case RA_CTYPE_UINT: return "uint ";
|
||||
case RA_CTYPE_FLOAT: return "float";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void ra_dump_tex_formats(struct ra *ra, int msgl)
|
||||
{
|
||||
if (!mp_msg_test(ra->log, msgl))
|
||||
@ -338,12 +348,7 @@ void ra_dump_tex_formats(struct ra *ra, int msgl)
|
||||
MP_MSG(ra, msgl, " NAME COMP*TYPE SIZE DEPTH PER COMP.\n");
|
||||
for (int n = 0; n < ra->num_formats; n++) {
|
||||
const struct ra_format *fmt = ra->formats[n];
|
||||
const char *ctype = "unknown";
|
||||
switch (fmt->ctype) {
|
||||
case RA_CTYPE_UNORM: ctype = "unorm"; break;
|
||||
case RA_CTYPE_UINT: ctype = "uint "; break;
|
||||
case RA_CTYPE_FLOAT: ctype = "float"; break;
|
||||
}
|
||||
const char *ctype = ctype_to_str(fmt->ctype);
|
||||
char cl[40] = "";
|
||||
for (int i = 0; i < fmt->num_components; i++) {
|
||||
mp_snprintf_cat(cl, sizeof(cl), "%s%d", i ? " " : "",
|
||||
@ -382,9 +387,10 @@ void ra_dump_imgfmt_desc(struct ra *ra, const struct ra_imgfmt_desc *desc,
|
||||
mp_snprintf_cat(pl, sizeof(pl), "%s", t);
|
||||
mp_snprintf_cat(pf, sizeof(pf), "%s", desc->planes[n]->name);
|
||||
}
|
||||
MP_MSG(ra, msgl, "%d planes %dx%d %d/%d [%s] (%s)\n",
|
||||
MP_MSG(ra, msgl, "%d planes %dx%d %d/%d [%s] (%s) [%s]\n",
|
||||
desc->num_planes, desc->chroma_w, desc->chroma_h,
|
||||
desc->component_bits, desc->component_pad, pf, pl);
|
||||
desc->component_bits, desc->component_pad, pf, pl,
|
||||
ctype_to_str(desc->component_type));
|
||||
}
|
||||
|
||||
void ra_dump_img_formats(struct ra *ra, int msgl)
|
||||
|
@ -531,6 +531,8 @@ struct ra_imgfmt_desc {
|
||||
int component_bits;
|
||||
// Like mp_regular_imgfmt.component_pad.
|
||||
int component_pad;
|
||||
// == planes[n].ctype (RA_CTYPE_UNKNOWN if not applicable)
|
||||
enum ra_ctype component_type;
|
||||
// For each texture and each texture output (rgba order) describe what
|
||||
// component it returns.
|
||||
// The values are like the values in mp_regular_imgfmt_plane.components[].
|
||||
|
@ -790,6 +790,8 @@ static void pass_get_images(struct gl_video *p, struct video_image *vimg,
|
||||
int csp = type == PLANE_ALPHA ? MP_CSP_RGB : p->image_params.color.space;
|
||||
float tex_mul =
|
||||
1.0 / mp_get_csp_mul(csp, msb_valid_bits, p->ra_format.component_bits);
|
||||
if (p->ra_format.component_type == RA_CTYPE_FLOAT)
|
||||
tex_mul = 1.0;
|
||||
|
||||
img[n] = (struct image){
|
||||
.type = type,
|
||||
@ -2296,6 +2298,7 @@ static void pass_convert_yuv(struct gl_video *p)
|
||||
|
||||
struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS;
|
||||
cparams.gray = p->is_gray;
|
||||
cparams.is_float = p->ra_format.component_type == RA_CTYPE_FLOAT;
|
||||
mp_csp_set_image_params(&cparams, &p->image_params);
|
||||
mp_csp_equalizer_state_get(p->video_eq, &cparams);
|
||||
p->user_gamma = 1.0 / (cparams.gamma * p->opts.gamma);
|
||||
|
Loading…
Reference in New Issue
Block a user